Passing an array as a function parameter in C++ Passing an array as a function parameter in C++ arrays arrays

Passing an array as a function parameter in C++


Use templates. This technically doesn't fit your criteria, because it changes the signature, but calling code does not need to be modified.

void doSomething(char charArray[], size_t size){   // do stuff here}template<size_t N>inline void doSomething(char (&charArray)[N]){    doSomething(charArray, N);}

This technique is used by Microsoft's Secure CRT functions and by STLSoft's array_proxy class template.


Without changing the signature? Append a sentinel element. For char arrays specifically, it could be the null-terminating '\0' which is used for standard C strings.

void doSomething(char charArray[]){    char* p = charArray;    for (; *p != '\0'; ++p)    {         // if '\0' happens to be valid data for your app,          // then you can (maybe) use some other value as         // sentinel    }    int arraySize = p - charArray;    // now we know the array size, so we can do some thing}

Of course, then your array itself cannot contain the sentinel element as content.For other kinds of (i.e., non-char) arrays, it could be any value which is not legal data. If no such value exists, then this method does not work.

Moreover, this requires co-operation on the caller side. You really have to make sure that the caller reserves an array of arraySize + 1 elements, and always sets the sentinel element.

However, if you really cannot change the signature, your options are rather limited.


In general when working with C or low-level C++, you might consider retraining your brain to never consider writing array parameters to a function, because the C compiler will always treat them as pointers anyway. In essence, by typing those square brackets you are fooling yourself in thinking that a real array is being passed, complete with size information. In reality, in C you can only pass pointers. The function

void foo(char a[]){    // Do something...}

is, from the point of view of the C compiler, exactly equivalent to:

void foo(char * a){    // Do something}

and obviously that nekkid char pointer contains no length information.

If you're stuck in a corner and can't change the function signature, consider using a length prefix as suggested above. A non-portable but compatible hack is to specify the array length in an size_t field located before the array, something like this:

void foo(char * a){    int cplusplus_len = reinterpret_cast<std::size_t *>(a)[-1];    int c_len = ((size_t *)a)[-1];}

Obviously your caller needs to create the arrays in the appropriate way before passing them to foo.

Needless to say this is a horrible hack, but this trick can get out of trouble in a pinch.