- Can I pass arrays to functions just as I would do with primitives such as int and bool?
- Can I pass them by value?
- How does the function know of the size of the array it is passed?
8 Answers
Can I pass arrays to functions just as I would do with primitives such as int and bool?
Yes, but only using pointers (that is: by reference).
Can I pass them by value?
No. You can create classes that support that, but plain arrays don't.
How does the function know of the size of the array it is passed?
It doesn't. That's a reason to use things like vector<T>
instead of T *
.
Clarification
A function can take a reference or pointer to an array of a specific size:
void func(char (*p)[13])
{
for (int n = 0; n < 13; ++n)
printf("%c", (*p)[n]);
}
int main()
{
char a[13] = "hello, world";
func(&a);
char b[5] = "oops";
// next line won't compile
// func(&b);
return 0;
}
I'm pretty sure this is not what the OP was looking for, however.

- 24,650
- 8
- 50
- 93
-
Upvoted because I was typing this exact same answer before it became visible. – May 19 '10 at 17:17
-
3Arrays in C++ can be passed by reference in which case you can know the size of the array. Of course, that doesn't apply for arrays created at run-time. – Khaled Alshaya May 19 '10 at 17:19
-
@AraK - Not sure what you mean here. Can you add an example to your answer? – egrunin May 19 '10 at 17:36
-
@egrunin: and it does not need to be templated: `void foo( int (&a)[10] )` will receive an array of exactly 10 integers by reference. The issue with dynamically allocated arrays is a little more complex... the type of `new int[10]` is `int *`, and not `int [10]`, but you can create dynamically an array of 10 integers: `int (*p)[10] = new int[1][10];` and then call the previous function: `foo(*p)`. – David Rodríguez - dribeas May 19 '10 at 17:58
-
@AraK, @David: I know the permutations, just wasn't sure we were thinking of the same one. Have appended a simple example. – egrunin May 19 '10 at 19:04
-
Your line `func(b)` does compile, and has undefined behaviour. `p` is a *pointer* parameter, not an array. The `char p[13]` in the signature of `func` is just replaced with `char *p`. To do what you want (and stop that line compiling), you could have `void func(char (&p)[13])`, as dribeas says. – Steve Jessop May 19 '10 at 20:58
-
@Steve - fixed. Overhasty cut-and-paste. – egrunin May 19 '10 at 21:28
-
@Steve: Fixed. This demonstrates [1] that edge cases take the most time [2] why this syntax is rarely encountered :) – egrunin May 20 '10 at 04:45
You can pass arrays the usual way C does it(arrays decay to pointers), or you can pass them by reference but they can't be passed by value. For the second method, they carry their size with them:
template <std::size_t size>
void fun( int (&arr)[size] )
{
for(std::size_t i = 0; i < size; ++i) /* do something with arr[i] */ ;
}
Most of the time, using std::vector
or another sequence in the standard library is just more elegant unless you need native arrays specifically.

- 94,250
- 39
- 176
- 234
-
That's hardly them carrying their size with them ;) The size is available as a template argument (or you could have a non-templated version with a suitable `const` defined somewhere). You can't get the size from `arr` itself which is where I think your current wording is a little misleading. – Troubadour May 19 '10 at 17:53
-
1@Troubadour: In c++ the size is not part of the array, but part of the type of the array. There is no need to add a `const` if you make it non-templated, the only difference is that it would work in arrays of exactly the size defined in the signature: `void foo( int (&a)[3] )` will only accept arrays of 3 integers. – David Rodríguez - dribeas May 19 '10 at 18:09
-
@dribeas: I didn't realise the bit about it enforcing the correct number of elements. That's nice, thanks for letting me know but it still doesn't make that number of elements available within the function which was my point. Also, I can't get `int N=10; void fun( int (&arr)[N] ) {}` to compile. Am I doing something wrong or are we at cross-purposes? – Troubadour May 19 '10 at 18:34
Can I pass arrays to functions just as I would do with primitives such as int and bool?
Yes, you can. Passing an array name as an argument to a function passes the address of the first element.
In short:
void foo(int a[]);
is equivalent to
void foo(int * a);
Can I pass them by value?
Not really. The "value" that gets passed with an array name is the address of the first element.
The only way to pass a copy of a C-style array is to wrap it in a class
or struct
that implements deep-copy semantics.
How does the function know of the size of the array it is passed?
It doesn't, unless you have your function take in an additional parameter that is the size of the array.

- 8,709
- 6
- 42
- 49
-
Re: equivalence between `int a[]` and `int * b`: there is one difference, though: the first form does not allow you to play with the pointer (e.g. `a++` is illegal). – Raphaël Saint-Pierre May 19 '10 at 17:31
-
@RaphaelSP, nope there is no difference like that. The first form does allow `a++` likewise - they are completely equivalent. @John, "There is no way to accept or pass a copy of a C-style array" is wrong when pedantically, though. If you wrap the array into a struct and take the struct by-value, the wrapped array is copied, and the function receives a copy of the c-style array. – Johannes Schaub - litb May 19 '10 at 18:06
-
@RaphaelSP: `void bar( int a[] ) { ++a; *a = 7; }` compiles both in g++ and comeau. – David Rodríguez - dribeas May 19 '10 at 18:06
-
Right -- I tried that as well -- I was going to say int * const a, then tried it and saw that you could modify the pointer. I'll clarify "no way" to something less absolute. – JohnMcG May 19 '10 at 18:49
-
@Johannes, @dribeas: Oh wow, I didn't know array variables and array parameters were different. So much for my infallible knowledge. – Raphaël Saint-Pierre May 19 '10 at 21:57
You can pass an array, but you must pass the size along with it if you want to know it for sure:
function(array, size);
Arrays are always passed by reference and the function can be written one of two ways:
Declaration: void function (class*, int);
Implementation: void function(class array[]; int size) {}
or
Declaration: void function (class*, int);
Implementation: void function(class *array; int size) {}
When you pass an array to a function the function in essence receives a pointer to that array, as seen in the second example above. Both examples will accomplish the same thing.

- 8,855
- 18
- 78
- 111
You can pass a std::vector
and similar well-designed object by value (though this is rather uncommon). Typically, you pass by reference or const reference.
A C/C++ array, as in
void foo(int x[])
is always passed by reference. Also, the function can not determine the true size of the argument passed in by the caller, you have to assume a size (or pass it as separate parameter).

- 40,917
- 20
- 104
- 186
-
3To be precise, the by-value syntax for arrays decays the array into a pointer to the first element and then passes that pointer by value. That differs from passing an array by reference: void foo( int (&a)[10] ) – David Rodríguez - dribeas May 19 '10 at 18:03
C-style arrays behave very strangely when passed into functions. For fixed-sized arrays, I would recommend std::array<int, 10>
instead, which can be passed by value like built-in types. For variable-sized arrays, I recommend std::vector<int>
, as suggested in other answers.

- 256,549
- 94
- 388
- 662
- Yes. For example:
void f(int a[]);
and call it like this:int myArr[size]; f(myArr);
- No, arrays are automatically passed by reference. You have to wrap your array in a struct or class if you want to simulate passing by value.
- It doesn't. You have to pass the size yourself.

- 43,099
- 13
- 111
- 179
-
1To be precise, the by-value syntax for arrays decays the array into a pointer to the first element and then passes that pointer by value. That differs from passing an array by reference: `void foo( int (&a)[10] )` – David Rodríguez - dribeas May 19 '10 at 18:02
Yes, you can pass them the same as primitive types. Yes, you can pass by value if you really wanted to with some wrapper code, but you probably shouldn't. It will take the size of the function prototype as the length - which may or may not match the incoming data - so no it doesn't really know.
Or!
Pass a reference or const reference to a vector and be safer and have the size info at your finger tips.

- 12,453
- 3
- 31
- 61