Considering the code as follows:
int i, a_size, s_size, n;
char **a;
a_size = 100; // examples
s_size = 10;
a = malloc(a_size * sizeof(char*));
for (int i = 0; i < a_size; i++)
a[i] = malloc((s_size) * sizeof(char));
Now, I would like to calculate how many elements there are inside the array dynamically (thus, ignoring a_size). Which is the proper way to do that?
In general you can't, and you should just take care of this kind of book-keeping yourself, but one possibility would be to store an additional row pointer set to NULL (aka a sentinel):
a = malloc((a_size + 1) * sizeof(char*)); // allocate additional row pointer
for (int i = 0; i < a_size; i++) // allocate rows
a[i] = malloc(s_size);
a[a_size] = NULL; // set sentinel row to NULL
Then you can determine the size by iterating through the row pointers until you find a NULL row. Note that this could be quite inefficient if you do it too often, or if the number of rows could be large.
TL;DR Pointers do not store any information regarding the allocated memory size. So, there is not straightway API kind of thing using which we can determine the allocated size.
However, some dynamic memory allocation libraries provide some options to actually fetch the information regarding the allocated size, but that's non-standard and heavily implementation dependent.
That said, you can think of an approach where you can explicitly mark the end of the data (check about the sentinel value concept) stored into the dynamically allocated memory (thus, essentially, marking the end of the allocated memory) but then also, it's something you have to take care of.
Please remember. as very rightly mentioned by Mr. Paul R, this sentinel value approach can be quite inefficient and there can be many limitations to this approach, like
and so on.
IMHO, best approach will be, keep the track of the size of allocation in a separate variable and pass that around with the pointer, as and when necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With