Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Length of array in function argument

Tags:

c

pointers

This is well known code to compute array length in C:

sizeof(array)/sizeof(type) 

But I can't seem to find out the length of the array passed as an argument to a function:

#include <stdio.h>  int length(const char* array[]) {   return sizeof(array)/sizeof(char*); }  int main() {   const char* friends[] = { "John", "Jack", "Jim" };   printf("%d %d", sizeof(friends)/sizeof(char*), length(friends)); // 3 1 } 

I assume that array is copied by value to the function argument as constant pointer and reference to it should solve this, but this declaration is not valid:

int length(const char**& array); 

I find passing the array length as second argument to be redundant information, but why is the standard declaration of main like this:

int main(int argc, char** argv); 

Please explain if it is possible to find out the array length in function argument, and if so, why is there the redundancy in main.


like image 426
Jan Turoň Avatar asked Nov 25 '11 12:11

Jan Turoň


People also ask

How do you find the length of an array in a function?

Using sizeof() function to Find Array Length in C++ The sizeof() operator in C++ returns the size of the passed variable or data in bytes. Similarly, it returns the total number of bytes required to store an array too.

Can we calculate size of array inside function?

Inside the function ar is a pointer so the sizeof operator will return the length of a pointer. The only way to compute it is to make ar global and or change its name. The easiest way to determine the length is size(array_name)/(size_of(int). The other thing you can do is pass this computation into the function.

Does array have size () or length ()?

Unlike the String and ArrayList, Java arrays do not have a size() or length() method, only a length property.

How do you declare the length of an array?

You can declare one-dimensional (1D) arrays with any non-negative size. int [] arr = new int[ 10 ]; // Array of size 10 int [] arr2 = new int[ 100 ]; // Array of size 100 int [] arr3 = new int[ 1 ]; // Array of size 1 int [] arr4 = new int[ 0 ]; // Array of size 0!

How do you pass the size of an array as a parameter?

The function clear() uses the idiom sizeof(array) / sizeof(array[0]) to determine the number of elements in the array. However, array has a pointer type because it is a parameter. As a result, sizeof(array) is equal to the sizeof(int *) .

Why do we pass size of array into function?

Passing the array size tells the function where the bounds are so you can choose not to go beyond them.


2 Answers

sizeof only works to find the length of the array if you apply it to the original array.

int a[5]; //real array. NOT a pointer sizeof(a); // :) 

However, by the time the array decays into a pointer, sizeof will give the size of the pointer and not of the array.

int a[5]; int * p = a; sizeof(p); // :( 

As you have already smartly pointed out main receives the length of the array as an argument (argc). Yes, this is out of necessity and is not redundant. (Well, it is kind of reduntant since argv is conveniently terminated by a null pointer but I digress)

There is some reasoning as to why this would take place. How could we make things so that a C array also knows its length?

A first idea would be not having arrays decaying into pointers when they are passed to a function and continuing to keep the array length in the type system. The bad thing about this is that you would need to have a separate function for every possible array length and doing so is not a good idea. (Pascal did this and some people think this is one of the reasons it "lost" to C)

A second idea is storing the array length next to the array, just like any modern programming language does:

a -> [5];[0,0,0,0,0] 

But then you are just creating an invisible struct behind the scenes and the C philosophy does not approve of this kind of overhead. That said, creating such a struct yourself is often a good idea for some sorts of problems:

struct {     size_t length;     int * elements; } 

Another thing you can think about is how strings in C are null terminated instead of storing a length (as in Pascal). To store a length without worrying about limits need a whopping four bytes, an unimaginably expensive amount (at least back then). One could wonder if arrays could be also null terminated like that but then how would you allow the array to store a null?

like image 156
hugomg Avatar answered Sep 17 '22 18:09

hugomg


The array decays to a pointer when passed.

Section 6.4 of the C FAQ covers this very well and provides the K&R references etc.


That aside, imagine it were possible for the function to know the size of the memory allocated in a pointer. You could call the function two or more times, each time with different input arrays that were potentially different lengths; the length would therefore have to be passed in as a secret hidden variable somehow. And then consider if you passed in an offset into another array, or an array allocated on the heap (malloc and all being library functions - something the compiler links to, rather than sees and reasons about the body of).

Its getting difficult to imagine how this might work without some behind-the-scenes slice objects and such right?


Symbian did have a AllocSize() function that returned the size of an allocation with malloc(); this only worked for the literal pointer returned by the malloc, and you'd get gobbledygook or a crash if you asked it to know the size of an invalid pointer or a pointer offset from one.

You don't want to believe its not possible, but it genuinely isn't. The only way to know the length of something passed into a function is to track the length yourself and pass it in yourself as a separate explicit parameter.

like image 40
Will Avatar answered Sep 18 '22 18:09

Will