writes:
> I'm seeking some answers about what seems to be a memory leak.
>
> I have a loop that looks much like this:
> double *largeArray = (double*) calloc();
> for (...) {
> printf("iteration #...\n");
> for (...) {
> double *foo = (double*) calloc();
> ....
> ....
> largeArray[someIndex] = something;
> free(foo);
> }
> }
>
> Though the actual code is larger, it only differs in 20+ lines of
> trivial math performed on stack variables.
>
> Clearly, foo cannot be leaking since it's being freed (and no, it
> cannot be allocated outside of the loop, since its size varies each
> time.
>
> Now, when I monitor memory usage with top it grows relatively quickly
> (300K per pass over the outer loop), thus there ought to be a memory
> leak. At first I thought that the "largeArray" was being optimized not
> to calloc all at once, but rather on demand, page by page (which would
> be bizzarre) but now I believe that might not be the case since the
> "largeArray" is about 4000*4000 of double which should be about 16MB -
> and I see usage of > 100MB after a few hundred iterations.
Apart from your miscalculation of the size allocated for largeArray,
there's no guarantee that free() gives memory back to the operating
system. Very likely it stays within your program and becomes
available for further allocation. You don't give us a clue about what
arguments you're giving to calloc(), but it's possible that you're
fragmenting the heap and making it difficult for the system to
re-allocate the memory you've freed.
I would probably add some printf() statements to log all the calls to
calloc() and free(). For example:
double *foo = calloc(something, something_else);
/*
* don't cast the result of malloc() or calloc().
*/
printf("foo = calloc("%lu, %lu) --> [%p]\n",
(unsigned long)something,
(unsigned long)something_else,
(void*)foo);
...
printf("free(foo), foo=[%p]\n", (void*)foo);
free(foo);
Analyze the results and make sure you're freeing everything you
allocate. If not, there's your problem; if so, the displayed
addresses may tell you something, or there may be some system-specific
way to trace the internal behavior of calloc() and free().
Incidentally, it's not safe to assume that calloc() will set all the
doubles in your allocated array to 0.0. It sets the allocated memory
to all-bits-zero. This is often the representation of 0.0, but the
language doesn't guarantee it.
--
Keith Thompson (The_Other_Keith)
kst- <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.