0

How to find size of char** array, I have been doing

int getSize(char** args)
{
   int size = (int)sizeof(args)/ (int)sizeof(arg[0]);
   return size;
}

But it is only returning the value 1. I cant seem to figure out how to find out how many elements are in my array of char*.

dreamcrash
  • 47,137
  • 25
  • 94
  • 117
  • There is no way to detect the size of an array that you have passed to a function because in the function it is no longer an array but a pointer. You have to do this in the calling function that knows the original array. – Bodo Mar 09 '21 at 15:24
  • Does this answer your question? [Knowing the size of the array using pointer](https://stackoverflow.com/questions/18570362/knowing-the-size-of-the-array-using-pointer) – user14063792468 Mar 09 '21 at 15:27
  • yeah that makes sense, so I just gotta set a seperate variable for this array when it is created so I can keep track of its size; – Colin Harker Mar 09 '21 at 15:31
  • Or you can do what strlen does, keep iterating while the current element doesn't equal NULL (like Andrew Henle's answer), however that'd have a worse time complexity than just keeping track of the size. – BidoTeima Mar 09 '21 at 15:36

3 Answers3

3

The standard way is used by argv and the environment table (in most implementations): terminate an array of char * pointers to strings with a NULL:

Array element   Points to
     0    ->    "string 0"
     1    ->    "string 1"
     2    ->    "string 2"
     .    ->        .
     .    ->        .
     .    ->        .
     N    ->    "string N"
    N+1   ->       NULL

So you'd count the size with something like:

int getSize(char** args)
{
    int size = 0;

    while ( args[ size ] )
    {
        size++;
    }

    return( size );
}
Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
2

The problem is that args is a pointer (actually a pointer to a pointer), not an array, so the sizeof trick doesn't work - you're dividing the size of a char ** by the size of a char * and on your machine they're the same, so you get a result of 1.

There's no metadata in a pointer value that tells you whether it's pointing to a single object or the first in a sequence of objects, or how many objects are in a sequence - that's information that has to be tracked separately.

As Andrew points out, in cases like this you usually have to rely on a sentinel value to mark the end of the sequence.

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

In c there is no “good” way to determine the size of an array. Because of this there are a lot of design patterns that either have statically size arrays or put some delimiter at the end to signal the end of the array (for example the null byte at the end of all strings).

So depending on your use case here it might make sense to pass an argc parameter whenever you would want to call getSize, or alternatively store a NULL at the end of the char** and iterate over the array until you find it:

// snake case is generally standard for c
int get_size(char** args)
{
    int i = 0;

    // check that the first element of each arg is not ‘\0’
    for ( ; args[i] != NULL; ++i) {
    }

    return i;
}

Without one of these approaches you are likely to encounter issues with accessing unallocated or freed memory, and there isn’t a good way to handle those, and any attempt to would certainly be less readable.

joshmeranda
  • 3,001
  • 2
  • 10
  • 24