Difference between passing array, fixed-sized array and base address of array as a function parameter
Solution 1:
All these variants are the same. C just lets you use alternative spellings but even the last variant explicitly annotated with an array size decays to a normal pointer.
That is, even with the last implementation you could call the function with an array of any size:
void func3(char str[10]) { }
func("test"); // Works.
func("let's try something longer"); // Not a single f*ck given.
Needless to say this should not be used: it might give the user a false sense of security (“oh, this function only accepts an array of length 10 so I don’t need to check the length myself”).
As Henrik said, the correct way in C++ is to use std::string
, std::string&
or std::string const&
(depending on whether you need to modify the object, and whether you want to copy).
Solution 2:
Note that in C++, if the length of the array is known at compile time (for example if you passed a string literal), you can actually get its size:
template<unsigned int N>
void func(const char(&str)[N])
{
// Whatever...
}
int main()
{
func("test"); // Works, N is 5
}
Solution 3:
In C++, use void func4(const std::string& str)
.
Solution 4:
These are all functionally identical. When you pass an array to a function in C, the array gets implicitly converted to a pointer to the first element of the array. Hence, these three functions will print the same output (that is, the size of a pointer to char
).
void func1(char* str) {
printf("sizeof str: %zu\n", sizeof str);
}
void func2(char str[]) {
printf("sizeof str: %zu\n", sizeof str);
}
void func3(char str[10]) {
printf("sizeof str: %zu\n", sizeof str);
}
This conversion only applies to the first dimension of an array. A char[42][13]
gets converted to a char (*)[13]
, not a char **
.
void func4(char (*str_array)[13]) {
printf("sizeof str_array: %zu\n"
"sizeof str_array[0]: %zu\n", sizeof str_array, sizeof str_array[0]);
}
char (*)[13]
is the type of str_array
. It's how you write "a pointer to an array of 13 char
s". This could have also been written as void func4(char str_array[42][13]) { ... }
, though the 42 is functionally meaningless as you can see by experimenting, passing arrays of different sizes into func4
.
In C99 and C11 (but not C89 or C++), you can pass a pointer to an array of varying size into a function, by passing it's size along with it, and including the size identifier in the [square brackets]
. For example:
void func5(size_t size, char (*str_array)[size]) {
printf("sizeof str_array: %zu\n"
"sizeof str_array[0]: %zu\n", sizeof str_array, sizeof str_array[0]);
}
This declares a pointer to an array of size char
s. Note that you must dereference the pointer before you can access the array. In the example above, sizeof str_array[0]
evaluates to the size of the array, not the size of the first element. As an example, to access the 11th element, use (*str_array)[11]
or str_array[0][11]
.