Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically calculate the size of a dynamically allocated memory

Tags:

c

malloc

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?

like image 567
vdenotaris Avatar asked Nov 20 '25 14:11

vdenotaris


2 Answers

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.

like image 158
Paul R Avatar answered Nov 22 '25 04:11

Paul R


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

  • You cannot have the sentinel value as one of the legit values.
  • In case, somehow the sentinel value does not appear at the very end of the allocation, it may provide wrong information about the allocated size.
  • You're always allocating some memory (to put the sentinel) which is not being used effectively.

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.

like image 44
Sourav Ghosh Avatar answered Nov 22 '25 04:11

Sourav Ghosh