40

I'm writing code which has a lot of 1 & 2 dimensional arrays. I got "error: can't allocate region" and I think its because too much memory is allocated. I use "malloc" and "free" functions, but I'm not sure I'm using them correctly. Maybe you know where I could see good examples on memory management in C?

so.. I just trying to get one algorithm work and for now this code is just function after function..

//memory allocation for 1D arrays
buffer = malloc(num_items*sizeof(double));

//memory allocation for 2D arrays
double **cross_norm=(double**)malloc(150 * sizeof(double *));
for(i=0; i<150;i++)
    {
        cross_norm[i]=(double*)malloc(num_items*sizeof(double));
    }
    
    //code
Window(N, window_buffer);
STFTforBMP(buffer,N,f, window_buffer);
getMagnitude(buffer,f, N, magnitude);
calculateEnergy(flux,magnitude, f);
calculateExpectedEnergy(expected_flux, candidate_beat_period, downbeat_location, f);
calculateCrossCorrelation(cross, flux, expected_values, f);
findLargestCrossCorrelation(&cross_max, cross, f);
normalizeCrossCorrelation(cross_norm, &cross_max, cross, f);
    ...............

How should I use the free function?

joel
  • 6,359
  • 2
  • 30
  • 55
andrey
  • 671
  • 1
  • 9
  • 20
  • 7
    Perhaps it would be more constructive to show us what you tried ? – cnicutar Jan 30 '12 at 18:59
  • you should provide examples of what you do. otherwise your question is just too general to answer beyond: read the specs. – akira Jan 30 '12 at 19:00

2 Answers2

56

You have to free() the allocated memory in exact reverse order of how it was allocated using malloc().

Note that You should free the memory only after you are done with your usage of the allocated pointers.

memory allocation for 1D arrays:

    buffer = malloc(num_items*sizeof(double));

memory deallocation for 1D arrays:

    free(buffer);

memory allocation for 2D arrays:

    double **cross_norm=(double**)malloc(150 * sizeof(double *));
    for(i=0; i<150;i++)
    {
        cross_norm[i]=(double*)malloc(num_items*sizeof(double));
    }

memory deallocation for 2D arrays:

    for(i=0; i<150;i++)
    {
        free(cross_norm[i]);
    }

    free(cross_norm);
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • `float* f_ptr1 = NULL;` `float* f_ptr2 = NULL;` `f_ptr1 = (float *)malloc(arry_size * sizeof(float));` `f_ptr2 = f_ptr1;` ... `free(f_ptr2)` – djsg Apr 10 '23 at 09:21
  • sorry, not sure how to add code in comment. Is memory released in the above code? – djsg Apr 10 '23 at 09:30
43

You actually can't manually "free" memory in C, in the sense that the memory is released from the process back to the OS ... when you call malloc(), the underlying libc-runtime will request from the OS a memory region. On Linux, this may be done though a relatively "heavy" call like mmap(). Once this memory region is mapped to your program, there is a linked-list setup called the "free store" that manages this allocated memory region. When you call malloc(), it quickly looks though the free-store for a free block of memory at the size requested. It then adjusts the linked list to reflect that there has been a chunk of memory taken out of the originally allocated memory pool. When you call free() the memory block is placed back in the free-store as a linked-list node that indicates its an available chunk of memory.

If you request more memory than what is located in the free-store, the libc-runtime will again request more memory from the OS up to the limit of the OS's ability to allocate memory for running processes. When you free memory though, it's not returned back to the OS ... it's typically recycled back into the free-store where it can be used again by another call to malloc(). Thus, if you make a lot of calls to malloc() and free() with varying memory size requests, it could, in theory, cause a condition called "memory fragmentation", where there is enough space in the free-store to allocate your requested memory block, but not enough contiguous space for the size of the block you've requested. Thus the call to malloc() fails, and you're effectively "out-of-memory" even though there may be plenty of memory available as a total amount of bytes in the free-store.

Jason
  • 31,834
  • 7
  • 59
  • 78
  • 4
    Is it just me or is that OP is asking something different and the answer (though nicely) explains something else? – Alok Save Jan 30 '12 at 19:31
  • 6
    The OP updated his question as I was typing my answer (I'm guessing in response to some of the comments) ... I thought my answer might be still be instructive even if it doesn't explicitly answer his updated question. His original question had no code and was basically that he's using `malloc` and `free`, but still ending up with a "can't allocate region" error. It sounded to me like possible memory fragmentation, so I thought this might be a good answer. – Jason Jan 30 '12 at 19:40
  • Ah I see. okay. It's a nice explanation though the changed Question makes it feel out of place.Anyways you have my +1 for the effort. – Alok Save Jan 30 '12 at 19:43
  • 2
    How would you fix such fragmentation? – RastaJedi Mar 06 '16 at 06:28
  • There's a number of options, but one descent strategy would be to use some type of custom small-block memory allocator that grabs a large chunk of memory from the OS, and then allocates memory from within that large block in a way that avoids memory fragmentation from random memory size allocations – Jason Mar 22 '19 at 15:12