Clean way to free double pointer in c - c

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.

Related

Explain how it's possible to allocate and free memory for a 2d array in C with just these 2 lines:

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.

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:
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.

how to get the size of array using the pointer to this array in C? [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 8 years ago.
I have the following code in C:
int array[5] = {0,1,2,3,4};
int * p = &array[0];
how to use the pointer p to get the size of this array p point to?
Sorry, this is actually impossible. The size of an array is not saved anywhere. You'll have to do it yourself.
It can't be done just from a pointer. The pointer is literally the address in memory of the first element of the array. The array size is not automatically associated with this pointer. You must keep track of the size yourself.
One workaround you can use is to reserve a special value for your array elements, say -1. If you can arrange for your last element to always have this value, then you can always find the end of the array by searching through it for that value. This is why strings have a null terminator, so strlen() and family can find the end of the string.
The short answer: In C, an array size cannot be retrieved from a pointer. The size must be passed separately.
The slightly-less-short answer: In C, a pointer is just an address to a spot in memory. The pointer does not even guarantee that there is a valid array or variable here; it is just a descriptor of a memory location.
In fact, in C, the concept of an array "size" is somewhat loose. A certain amount of consecutive memory can be allocated, but there is no checking as to if a pointer leaves this memory.
For example:
int a[] = {1, 2, 3};
int b = a[7];
will compile properly. C does not have any bounds checking!
you can not know the size of array using pointer to it. you cant determine since there is no way to know the end of array or to know that we reached the last element of array.
So, after reading 5 previous answers, here a better one:
a) You cannot get the element count of an array using a pointer.
Common workaround are:
Using a sentinel value (see C-String aka asciiz)
Passing the length separately. (see counted strings using mem*())
Actually using a struct, resp. reserving element 0 (or -1) for a lenght value. (also see counted strings).
Just allocate a whopping big amount of memory you know will suffice and not bother with the actual length at all. Getting this wrong is fun and easy to do.
b) You can get the element count of an array using the array name:
struct foo[my_expr];
ìnt count = sizeof array / sizeof *array;

is there a difference between malloc ** and *

I am wondering if there is a difference between doing this
char ** str;
str=(char **)malloc(sizeof(char*) * ARRAY_LEN);
and doing this :
str=(char*)malloc(sizeof(char)* ARRAY_LEN);
for(i=0;i<ARRAY_LEN;i++)
*(str+i)=(char*)malloc(sizeof(char)* ARRAY_LEN);
and doing this is the same too :
char str[ARRAY_LEN][ARRAY_LEN];
Yes, one is a pointer to a pointer to char, and the other is a pointer to char, there is a very big difference. between those. You can think of it as an array of strings in the first case, and a single string in the second.
Of course, in the first case you have to somehow allocate memory for the actual strings in the "array".
It all depends on what you want to achieve. I guess it is an array of strings, but maybe neither of your snippets will perform what you want. So let's go over them:
char ** str;
str=(char **)malloc(sizeof(char*) * ARRAY_LEN);
str is a pointer to a pointer to char. This could indeed be used for that purpose. The malloc then properly allocates space for ARRAY_LEN number of pointers to char, also OK for the intended purpose. The problem may lie in that there are no actual strings allocated, that is, all the ARRAY_LEN pointers to char are left pointing to God knows where (malloc() does not initialize them, not even to NULL). One way to properly finish this up would be setting all the pointers to NULL indicating your string list is empty.
str=(char*)malloc(sizeof(char)* ARRAY_LEN);
for(i=0;i<ARRAY_LEN;i++)
*(str+i)=(char*)malloc(sizeof(char)* ARRAY_LEN);
I assume str is still a pointer to a pointer to char. Then the cast itself will be invalid, as well as occupying just ARRAY_LEN bytes (sizeof(char) evaulates to 1) for ARRAY_LEN number of pointers (well, undefined as soon as you try to access all those...). The second part, the for loop would be OK for completing the first scenario if you wanted a rectangular array of chars, but this case the assignment to *(str+i) will likely cause a segfault when the loop starts writing outside the insufficient storage allocated for str.
char str[ARRAY_LEN][ARRAY_LEN];
This is a plain rectangular 2 dimensional array of chars. Note that it is conceptually different from both of the above! str can't decay to have an equal meaning to char ** str above since it's 2 dimensional (one dimensional arrays may decay to pointers as needed).
In all three cases it seemed you tried to get a rectangular (ARRAY_LEN * ARRAY_LEN) storage of characters, in the first two in the form of double indirection, in the last as a 2 dimensional array. This might not be what you wanted to do, probably you rather wanted to get an array of strings. If you don't know anything about the strings in advance, and neither their maximum length, this is more complicated to perform properly (you might want to handle all strings separately, by some means depending on use case figuring out their length, and allocating accordingly - probably even needing coding dynamically growing storage). Otherwise if you know or can limit the maximum length (pay attention to a terminating zero), you may allocate accordingly, and then limit the string lengths while you read them in.
Hope it helps.

How do I (deep) copy an array in C?

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).

Resources