tags:

views:

82

answers:

2

I want to use the git's malloc and realloc wrappers in my code for OOM(out of memory) conditions. Here is its code:

void *xmalloc(size_t size)
{
      void *ret = malloc(size);
      if (!ret && !size)
              ret = malloc(1);
      if (!ret) {
              release_pack_memory(size, -1);
              ret = malloc(size);
              if (!ret && !size)
                      ret = malloc(1);
              if (!ret)
                      die("Out of memory, malloc failed");
      }
#ifdef XMALLOC_POISON
      memset(ret, 0xA5, size);
#endif
      return ret;
}

but the release_pack_memory function is in sha1_file.c header file and this function have references to the functions in other header files in Git's code and I didn't want to put so much effort for isolate this function from Git's codebase. At the moment I am looking for an alternative function for release_pack_memory function, or can you recommend me another alternative. I'll be thankful for any kind of help

+1  A: 

Just remove the whole block containing the call to that function. It serves no use.

Further, on modern systems with virtual memory and overcommit, testing the return value of malloc is fairly useless. It's possible to get a pointer and still have your program crash when you try to write to it. An approach used in one major project I code for is to always write to a low/zero offset immediately after malloc. If malloc returned null or if there's no physical memory for copy-on-write to work, the program will just immediately crash, which is about the best you can hope for in most out-of-memory situations. (On the other hand, writing to a large offset without testing malloc for failure can be disastrous since it could clobber other memory if malloc returned null due to requesting an unrealistically-large buffer.)

R..
+5  A: 

Why do you want to use Git's malloc wrapper? Do you understand what it's doing? If so, why do you think you need a "replacement" for release_pack_memory?

All this wrapper does* is, if malloc fails, it tries to free up some memory that it uses for caches (which is what release_pack_memory does) and then tries again. If you don't have any in-memory caches then there's really no point copying this wrapper (and if you do have in-memory caches, then you should already know how to free memory from it without having to copy this function).


* It also contains a check for if size is 0 on platforms that do not support malloc(0), if this is a concern to you, then the release_pack_memory stuff is still useless.

Dean Harding
@Dean,Yeah I thought that I understood this code. But I missed the point that it was freeing up from its own cache :). And I do have in-memory caches.
systemsfault
@systemsfault: sure, the logic is basically just "if `malloc` fails, free at least `size` bytes from cache and try again".
Dean Harding
No, the size 0 check is not for platforms that don't support malloc(0). It's for callers that expect the stupid GNU behavior of returning a non-NULL pointer on malloc(0). Most sane people agree it's best for malloc(0) to return NULL.
R..