简体   繁体   中英

How many calls to free() are needed for `pixel (*copy)[rows] = malloc(cols * sizeof (*copy))`

I have seen various suggestions to allocate 2D arrays in C99 with expressions like this:

int (*array)[cols] = malloc(rows * sizeof *array);

I want to know three things:

  1. Is the entire structure allocated on the heap? Or is this actually a bunch of pointers (on the stack) pointing to arrays on the heap..?

  2. Is the allocated memory completely contiguous?

  3. Is it true that only one call, free(array) , is needed to free the whole 2D structure? I read this somewhere - can't remember where - and it seems to work for me, but I'd like to understand why.

(1) Is the entire structure allocated on the heap? Or is this actually a bunch of pointers (on the stack) pointing to arrays on the heap..?

The entire structure (everything that malloc allocates) is on the heap.

(2) Is the allocated memory completely contiguous?

Yes, malloc allocates a contiguous region of storage.

(3) Is it true that only one call, free(array), is needed to free the whole 2D structure? I read this somewhere - can't remember where - and it seems to work for me, but I'd like to understand why.

Yes, it's true. As to the why of it, why would it be any other way? You allocate a single region of storage using malloc , and free is used to de-allocate a single region of storage that was returned by a prior malloc .

I suspect you're confused by the declaration type, though you don't mention it:

int (*array)[cols]

This means that the array variable becomes a single pointer (which is itself allocated on the stack) to an array-of- int with cols elements (which is allocated on the heap due to the use of malloc ). Compare this to the more common:

int *array[cols] 

... which instead declares a 1-dimensional array of pointers (where the array itself will be on the stack). You might use this latter to create an array-of-pointers-to-arrays, by storing a pointer to a series of arrays in each element (arrays which you would indeed have to allocate and free individually!). This kind of construction can be used in a similar way to a 2D array, but is not really the same thing.

Remember also that a pointer in C can always point at an array. So, even though the first declaration declares a pointer to a 1-dimensional array, it can be used to point at an array of such arrays, ie a 2-dimensional array as you wanted. And indeed, the malloc call allocates storage for such an array:

malloc(rows * sizeof *array);

here, sizeof *array is the size in bytes of a (single) 1D array with cols elements. When multiplied by the number of rows, it yields the storage requirement of a 2D array with size rows × cols .

C does not do hidden memory allocation. The type in the question can be used as a true 2D array. Actually it is a "pointer to array[ cols ] of int ".

OTOH, something like int *array[cols] (note the missing parenthesis) is not a 2D array, but an "array of pointers to int ". Yet even here you have to malloc the array and each row explicitly!

And for every malloc you need a corresponding free .

Note that the C standard does not require a heap, stack or any other specific management structure. This is left to the implementation. However, most hosted environments (ie full-sized run-time) use something like a heap.

Remember to check the result of malloc and handle allocation failure appropriately.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM