3

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?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
vdenotaris
  • 13,297
  • 26
  • 81
  • 132
  • 7
    You can't do that - you need to take care of this kind of book-keeping yourself. – Paul R Aug 19 '15 at 13:08
  • 5
    You can't. There's no way to examine a dynamically allocated C array and magically determine its size. – Paul Roub Aug 19 '15 at 13:09
  • Yes, but interestingly, for `free` no size is given as argument either. Although to my knowledge there is no specified way to access the internal bookkeeping, the information of the size of the allocated memory area must be stored somewhere internally. – Codor Aug 19 '15 at 13:11
  • 2
    You could have an `size_t s[100]` to store the sizes in dynamically, then just do a lookup. – Jonas Byström Aug 19 '15 at 13:11
  • 2
    This has been asked and answered: http://stackoverflow.com/questions/37538/how-do-i-determine-the-size-of-my-array-in-c – o_weisman Aug 19 '15 at 13:12

4 Answers4

4

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.

Paul R
  • 208,748
  • 37
  • 389
  • 560
3

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.

Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

First of all dynamically you allocated 101 one-dimensional arrays.

The total number of allocated characters are equal to the product s_size * s_size.

You could use a sentinel but in general it is difficult to select a value for the sentinel.

So you should store these values in variables yourself.

You need to determine the length of a string stored in one one-dimensiobal array with elements of type char you should use standard C function strlen declared in header <string.h> For example

strlen( a[0] )
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

One possibility to implement the desired bookkeeping mechanism (although this might not be a good approach) would be to implement custom allocation, size and free functions which can be sketched in the following way, where size_t is the type used for the size of arrays; the approach is similar to the Pascal style strings.

For the allocation, allocate sizeof(t_size) memory more, write it to the beginnig of the allocated block, and return a pointer just pointing after the first sizeof(t_size) bytes.

To obtain the size, just look sizeof(t_size) bytes before the array.

For the free function, deallocate the memory block beginning at the position where the size is stored, which is the beginning of the block that was actually allocated.

Codor
  • 17,447
  • 9
  • 29
  • 56