Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

array_length in C

Tags:

arrays

c

I wrote an array_length function like this:

int array_length(int a[]){
    return sizeof(a)/sizeof(int);
}

However it is returning 2 when I did

unsigned int len = array_length(arr);
printf ("%i" , len);

where I have

int arr[] = {3,4,5,6,1,7,2};
int * parr = arr;

But when I just do

int k = sizeof(arr)/sizeof(int);
printf("%i", k);

in the main function, it returns 7.

What is the correct way to write the array_length function and how do I use it?

like image 490
SuperString Avatar asked Jan 18 '10 20:01

SuperString


4 Answers

Use a macro...

#define SIZEOF_ARRAY( arr ) sizeof( arr ) / sizeof( arr[0] )

It'll also have the bonus of working for any array data type :)

like image 100
Goz Avatar answered Nov 16 '22 00:11

Goz


Your function won't work. C arrays and C pointers are different types, but the array will degenerate into a pointer if you look at it funny.

In this case, you're passing the array as a parameter, and it's turning into a pointer in the call, so you're measuring the sizeof(int *)/sizeof(int).

The only way to make this work is to use a macro:

#define ARRAYSIZE(x) (sizeof(x)/sizeof(*x))

and that will only work if x is declared in that scope as an array and not as a pointer.

like image 42
David Thornley Avatar answered Nov 16 '22 01:11

David Thornley


The simple answer to your question is: there is no way to write the array_length function. You might be able to get away with a macro definition, but that depends upon the context in which you will use the macro.

You have made the common mistake of confusing arrays and pointers in C. In C, an array's name, in most cases, is equivalent to a pointer to its first element. Your array_length function receives an array a in such a context. In other words, it is impossible to pass an array as an array in C. You function is as if it is defined like this:

int array_length(int *a){
    return sizeof(a)/sizeof (int);
}

which, basically divides the size of int * by the size of int. Also, by the above description, it is impossible to know the size of an array in C in a function.

Now, how can you determine its size properly outside of the function? The answer is that sizeof operator is one of the cases where the name of an array does not reduce to a pointer to its first element. I have explained the differences more elaborately in this answer. Also note that despite appearances, sizeof is an operator, not a function (as we just learned, it can't be a function, because then it won't be able to calculate the size of an array).

Finally, to determine the size of an array a of any type T, I prefer:

size_t sz = sizeof a / sizeof a[0];

The above is type-agnostic: a could be of any type above. Indeed, you could even change the type of a and would not need to change the above.

like image 21
Alok Singhal Avatar answered Nov 16 '22 00:11

Alok Singhal


there is no way to determine the size of an array passed into a function like this

 void foo(int a[]);

there is not enough information at compile time or at run time to work it out

The sizeof tricks only work in source locations where the array size is specified

like image 24
pm100 Avatar answered Nov 16 '22 00:11

pm100