Does realloc function in C allocate contiguous memory space?
I am trying to implement dynamic integer array. Should I increment pointer by size of array element or by 1?
Are there any other better ways to implement dynamic array in C?
Yes, just like malloc() does.
If you have an int* ptr which is a pointer to an element of a dynamically allocated int array, a simple ptr++ will point to the next element.
Using malloc() and realloc() in C seems to me a good option for dynamic arrays.
Does realloc function in C allocate contiguous memory space?
Yes.
I am trying to implement dynamic integer array. Should I increment pointer by size of array element or by 1?
You should increase your pointer by 1.
Are there any other better ways to implement dynamic array in C?
Using malloc family functions is the only way. But in C99 and latter you can use variable length arrays (but it has some limitations as it allocates memory on stack).
Related
When you pass an array to a function, does it allocate memory not for the array but for the address of the first element of the array?
All function arguments are passed on the stack (which is a memory space reserved for that purpose). Compiler optimisations might avoid stack usage by holding the values in registers, but you should work on the basis that the size of the argument is allocated to stack.
Note that in C, parameters are either integral values (int, char, etc) or pointers. Objects/Arrays are only ever a pointer to the first element/base (or pointer to pointer etc).
I am dynamically allocating a double pointer (char **pointer), some methods later the information about the length is no longer known.
Is there a clean way to free both the "pointer array" and the "char array"s, without knowing the length of the pointer array?
There's technically a way.
If you allocate one extra pointer, and set the last one to NULL, you can free all of the double arrays and then the double array array by freeing until you reach NULL. It's a similar principle to strings.
You shouldn't probably need this, though.
I can only think of using perhaps index 0 of the array as the total length of it.
int (*mapTerrain)[10] = (int (*)[10])malloc(sizeof(int[10][10]));
free(mapTerrain);
Someone on this site suggested these 2 lines for working with dynamical 2d arrays in C. Dimensions are [10][10]. Problem is, I'm not sure I understand them correctly. If I had to explain these 2 lines I'd say the following:
On the left we have an array of int pointers with size 10. (Can't explain the casting, I myself would expect it to be int *).
What's being passed to malloc is an array of int-s sized [10][10]. (Why isn't it ...malloc(sizeof(int*10*10));?) What allows us to pass an array to malloc instead of size_t size?
As for the free(mapTerrain); line. How come one free is enough? From what I remember you have to call free for every row of a dynamical 2d array.
The cast of the result of malloc is just clutter and not necessary.
The most correct, formal version would be:
int (*mapTerrain)[10][10] = malloc(sizeof(int[10][10]));
This is an array pointer to a int [10][10] array. However, such a pointer is a bit painful to work with in practice, since to get an item we have to do:
*mapTerrain to get the array pointed at from the array pointer.
(*mapTerrain) parenthesis to not trip over operator precedence.
(*mapTerrain)[i][j] to get a single item.
As a trick, we can instead use a pointer to the first element of the int[10][10]. The first element is of type int[10], and so an array pointer to that element is int(*)[10]. With this type, we can do mapTerrain[i][j] as expected, because i means "give me array number i" through pointer arithmetic.
This trick is essentially the same thing as when we do something like
char* ptp = malloc(sizeof("hello"));`
Here we don't point to the whole array either, we point at the first element of it.
sizeof(int[10][10]) is 100% equivalent to sizeof(int*10*10) (or 400 for that matter), but the first is self-documenting code, showing that we are expecting to use the allocated data as an array int[10][10].
One free is enough because there is just one malloc. You allocate the whole 2D array as a contiguous chunk of memory.
Further reading: Correctly allocating multi-dimensional arrays.
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:
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..?
Is the allocated memory completely contiguous?
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, i.e. 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 (i.e. full-sized run-time) use something like a heap.
Remember to check the result of malloc and handle allocation failure appropriately.
Refering to http://www.devx.com/tips/Tip/13291, it says that I can use memcpy with the size to copy determined by sizeof(), however, isn't the array pointing to a pointer?
Other than iterating through the array, how can I use memcpy to deep copy an array?
Thanks!
In the linked example int weekly_hours[5][5]; allocates space for 25 integers. There is no further indirection, so you can safely use memcpy to duplicate it's values.
A multi-dimensional array is contiguously allocated. An array of pointers (of pointers...) is a different thing (and each sub-pointer should be allocated/copied/freed on its own).
Do not be confused by the fact that an unidimensional array and a single pointer can be used interchangeably in most situations, because they are not technically the same.
To hopefully clear up some of the confusion:
An array is a chunk of allocated,
adjacent memory cells.
An array variable name can transform ("decay") into a pointer to the first element of the array, but not the other way around. This is done implicitly each time you use the array variable name in pointer arithmetics.
You can use the sizeof() operator on the variable name of any statically alloced array, to get the number of bytes in the array. If sizeof() is used on a statically allocated, multi-dimensional array, the same applies.
If you use the sizeof() operator on a
pointer, you will get the size of a
pointer (i.e. 4 bytes on a 32-bit
machine).