C++ - Size of an array pointer

Asked

Viewed 3,219 times

8

I have an array:

char *exemplo[] = {"item1", "item2", "item3"};

And a function:

void myFunc(**myArray)
{

}

So, I want a function that returns the size of this array that I passed as parameter. For example if I passed the array exemplo the function should return 3.

I know how to do this outside the function, but when I pass as parameter not the right one.

  • "I know how to do it out of function" just out of curiosity, how is it done? I thought it was impossible... But I’ve never worked in depth with C/C++, so I may (I must) be wrong.

  • 3

    sizeof(example) / sizeof(*example)

  • Just out of curiosity, the function main(int argc, char **argv) remembers your problem.

2 answers

5


Given an array:

int array[] = {3, 1, 4, 1, 5};

And a function:

int funcao(int* argumento) {}

The moment you call the function occurs a array decay for pointer.

funcao(array);

And from that moment it is not possible to know the size of the array at all. All that remains is a pointer to the first element. Usually the array size is passed as an additional argument. Note that the following also does not work:

int funcao(int argumento[]) {}
int funcao(int argumento[50]) {} // Você poder por qualquer número ali. É ignorado.

This is just another syntax for exactly the same thing. You’re taking a pointer as an argument.

However there is a way to resolve this. Instead of passing the argument as value, you can use a reference to an array. Thus:

int funcao(int (&argumento)[5]);

Now the size of the array is mandatory and it does make a difference. There is no decay here and you call in the same way as before: funcao(array). If you call with an array of size other than 5 there will be a compilation error.

This is where the templates magic comes in. If there is only one acceptable size for the argument, let’s make the compiler deduct that value for us:

template <typename T, int S>
int size(T (&arg)[S]) { return S; }

Given an array of S elements of the type T, the function will return the value of S.

Example:

int array1[] = {3, 1, 4, 1, 5};
char* array2[] = {"item1", "item2", "item3"};

cout << size(array1) << endl; // 5
cout << size(array2) << endl; // 3

You can now do some computation within the function, since you have the size. But remember that you took the array by reference. So anything that changes in it will affect the variable passed as argument.

  • our ! was really worth ! I thought of passing as parameter too, but I thought it best to already take advantage of the array I passed to get the size

  • 1

    References to array are an interesting business that C++ added to C, but I wonder if doing so with templates, we would not have the case of the compiler generating in the generated code a copy of the function for each different size we use... (as this is usually how templates work). In this case the "manual" mode, passing separately the array/pointer and its size is more advantageous.

  • 1

    @Probably this would happen, but on the other hand the number of arrays whose size is known at compile time is finite, for everything else this technique would not apply (that I know; I repeat that my experience with C/C++ is well dated). And anyway, the compiler would probably make these functions inline even...

  • @If you pass the size argument hardcoded in the function call, the compiler will perform constant propagation optimization and create copies of the function for each argument anyway (this in -O3). The problem with doing so is that you can make the wrong argument. A solution is to make the template function in which the only thing you have in the body is to call an auxiliary function by passing the S as argument. You can also use attributes to prevent inline if you like. But doing this is almost micro-optimization. Generally leave to the compiler this work.

0

Anyway it becomes useless to pass the matrix by reference and still pass the number of elements of it in which simply could pass the number of elements by another parameter.

The ideal would be for the function itself to calculate the number of elements in the matrix, but this becomes impossible because the C passes only her pointer and calculus with sizeof() or even with templates would not have the expected result.

I’m working on a code like this:

#include <stdio.h>

int LenArray(char *a[])
{
   int nlen = 0;
   //while(*(a+nlen)){
   while( a[nlen] ){
     nlen++;
   }
   return nlen;
}

void main(void)
{
   char *menu[] = {"Incluir", "Remover", "Listar", "Imprimir", 0};
   printf("Tamanho do Array: %d\n", LenArray(menu));
}

Upshot:

Tamanho do Array: 4  
  • This code is wrong! To work, the variable menu should have been declared so: char *menu[] = { "Incluir", "Remover", "Listar", 0 };. And it would be more intelligible if you’d used a[x] instead of *(a+x). Better still get in place x had used i.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.