1

When print_array is called, the size of the int array[] parameter (count) isn't what was expected. It seems sizeof is not returning the size of the entire array which would be 5*sizeof(int) = 20.

namespace Util { void print_array(int array[]) { size_t count = (sizeof array)/(sizeof array[0]); cout << count; // int count = sizeof(array)/sizeof(array[0]); // for (int i = 0; i <= count; i++) cout << array[i]; } } int array_test[5]={2,1,5,4,3}; Util::print_array(array_test); 
2
  • 1
    Yeah, this is a pretty annoying case in C and C++. It should mean to pass a copy of the array by value, but instead there are special rules that mean it's just like void print_array(int * const array); Also annoying, functions are explicitly forbidden from returning arrays by value even though C otherwise has the syntax: int f()[10]; In C++11 this is all fixed by using std::array. Commented Oct 13, 2011 at 15:45
  • Your code is valid C++, and not valid C. The expression "C array", in a C++ context, is not very meaningful; maybe in a few years "array" in a C++ context will mean an instance of std::array by default, so that "C array" would make sense, but that isn't the case yet. Commented Oct 13, 2011 at 16:18

8 Answers 8

8

int array[] here becomes int* array, and sizeof(array) returns the same thing sizeof(int*). You need to pass an array by reference to avoid that.

template <size_t N> void print_array(int (&array)[N]) { std::cout << N; } int array[] = { 2, 1, 5, 4, 3 }; print_array(array); 
Sign up to request clarification or add additional context in comments.

Comments

2

Read this: it says the way to fix this, but for a quick description:

When a function has a specific-size array parameter, why is it replaced with a pointer?

Using sizeof(array) will work in the scope that the array is statically defined in. When you pass it into a function though the type gets converted into a pointer to the array element type. In your case, when you're in print_array it is an int*. So, your sizeof in in the function will be the size of a pointer on your system (likely 32 or 64 bits).

You can get around this with some fancy syntax like so (from the link above):

If you want that the array type is preserved, you should pass in a reference to the array:

void foo ( int(&array)[5] ); 

but I'd say just pass the size in as well as another parameter, its more readable.

2 Comments

Pass by reference, pointer, and by value are the three primary constructs for passing information to fuction. By value creates a copy, by reference references the entire object, and by pointer points the first address
Was there an issue related to this in the solution?
1

As this array is implemented as a thin overlay on pointers, the variable you have is just a pointer, so sizeof will return the size of your pointer.

The only way to know the length of an array is to place a terminating object, as the null character in C strings.

There is no other way to determine the size of an array if you only have a pointer to it.

Comments

1

Here's a trick: you can take a reference to an array of fixed size. You can use this to template-deduce the size.

#include <iostream> char a [22]; char b [33]; void foo (char *, size_t size) { std :: cout << size << "\n"; } template <size_t N> void foo (char (&x) [N]) { foo (x, N); } int main () { foo (a); foo (b); } 

This prints 22\n33\n

Comments

0

void print_array( int array[] ) is synonymous with void print_array( int *array ). No size information is passed when the function call is made, so sizeof doesn't work here.

Comments

0

For an algorithm like this, I like to use iterators, then you can do what you want... e.g.

template <typename Iterator> void print(Interator begin, Iterator end) { std::cout << "size: " << std::distance(begin, end) << std::endl; std::copy(begin, end, std::ostream_iterator<std::iterator_traits<Iterator>::value_type>(std::cout, ", ")); } 

to call

print(a, a + 5); // can calculate end using the sizeof() stuff... 

Comments

0

just an addition to all the answers already posted:

if you want to use an array which is more comfortable (like an ArrayList in java for instance) then just use the stl-vector container which is also able to return its size

Comments

0

All the following declarations are exactly same:

void print_array(int array[]); void print_array(int array[10]); void print_array(int array[200]); void print_array(int array[1000]); void print_array(int *array); 

That means, sizeof(array) would return the value of sizeof(int*), in all above cases, even in those where you use integers (they're ignored by the compiler, in fact).

However, all the following are different from each other, and co-exist in a program, at the same time:

void print_array(int (&array)[10]); void print_array(int (&array)[200]); void print_array(int (&array)[1000]); int a[10], b[200], c[1000], d[999]; print_array(a); //ok - calls the first function print_array(b); //ok - calls the second function print_array(c); //ok - calls the third function print_array(d); //error - no function accepts int array of size 999 

Comments