I am coding a 3D array using triple pointers with malloc
.
First of all, there is no need for any array to be allocated using more than one call to malloc
. In fact, it is incorrect to do so, as the word "array" is considered to denote a single block of contiguous memory, i.e. one allocation. I'll get to that later, but first, your question:
Question: what's the difference when used as the operand of sizeof
?
The answer, though obvious, is often misunderstood. They're different pointer types, which coincidentally have the same size and representation on your system... but they might have different sizes and representations on other systems. It is important to keep that possibility in mind, so that you can be sure your code is as portable as possible.
Given size_t row=3, col=4, dep=5;
, you can declare an array like so: Date array[row][col][dep];
. I know you have no use for such a declaration in this question... Bear with me for a moment. If we printf("%zu\n", sizeof array);
, it'll print row * col * dep * sizeof (Date)
. It knows the full size of the array, including all of the dimensions... and this is exactly how many bytes are required when allocating such an array.
printf("%zu\n", sizeof ptrDate);
with ptrDate
declared as in your code will produce something entirely different, though... It'll produce the size of a pointer (to pointer to pointer to Date
, not to be confused with pointer to Date
or pointer to pointer to Date
) on your system. All of the size information, regarding the number of dimensions (e.g. the row * col * dep
multiplication) is lost, because we haven't told our pointers to maintain that size information. We can still find sizeof (Date)
by using sizeof *ptrDate
, though, because we've told our code to keep that size information associated with the pointer type.
What if we could tell our pointers to maintain the other size information (the dimensions), though? What if we could write ptrDate = malloc(row * sizeof *ptrDate);
, and have sizeof *ptrDate
equal to col * dep * sizeof (Date)
? This would simplify allocation, wouldn't it?
This brings us back to my introduction: There is a way to perform all of this allocation using one single malloc
. It's a simple pattern to remember, but a difficult pattern to understand (and probably appropriate to ask another question about):
Date (*ptrDate)[col][dep] = malloc(row * sizeof *ptrDate);
Suffice to say, usage is still mostly the same. You can still use this like ptrDate[x][y][z]
... There is one thing that doesn't seem quite right, though, and that is sizeof ptrDate
still yields the size of a pointer (to array[col][dep] of Date
) and sizeof *ptrDate
doesn't contain the row
dimension (hence the multiplication in the malloc
above. I'll leave it as an exercise to you to work out whether a solution is necessary for that...
free(ptrDate); // Ooops! I must remember to free the memory I have allocated!