0

Consider the code below. This generates the following output:

Length: 64 Testfn: 8 Length again: 64

I am having trouble understanding why the output at the test-function is not equal to the output at the main function. Taking into account that the output at the test-function is equal to 8, I assume that this is because sizeof(arg) gets the size of the pointer instead of the array itself.

This would all seem very logical to me, but why doesn't sizeof give that same value in the main function? And how would I fix it? I have tried several things with dereferencing, but this does not seem to give any difference whatsoever.

#include <iostream>

void test(int arg[]) {
    std::cout << "Testfn: " << sizeof(arg) << std::endl;
}

int main() {
    int int_arr[16];
    std::cout << "Length: " << sizeof int_arr << std::endl;
    test(int_arr);
    std::cout << "Length again: " << sizeof int_arr << std::endl;
}
Pieter De Clercq
  • 1,951
  • 1
  • 17
  • 29
  • 2
    And this is exactly why you need to pass the length as an argument (C) or use `std::vector`/`std::array` (C++). – crashmstr May 23 '17 at 19:26
  • See https://stackoverflow.com/questions/6567742/passing-an-array-as-an-argument-to-a-function-in-c, which applies equally to C++. – John Bollinger May 23 '17 at 19:28
  • 469 and you didn't do some research? :/ For example check this [question](https://stackoverflow.com/questions/1975128/why-isnt-the-size-of-an-array-parameter-the-same-as-within-main). – gsamaras May 23 '17 at 19:28
  • 2
    @gsamaras shaming them for making a mistake is never the right thing to do – TankorSmash May 23 '17 at 19:34
  • If you want to characterize disregarding our community standards or not bothering to learn them in the first place as "a mistake", @TankorSmash, then I assert that it is one that *does* warrant a community response. I see nothing here that appears to go too far in that direction. – John Bollinger May 23 '17 at 20:07
  • @JohnBollinger they made it personal. Regardless of what they ended up saying, using the person's traits in relation to an argument is uncool. It's not about the asker, it's about the question. – TankorSmash May 23 '17 at 20:32

2 Answers2

3

The function parameter

void test(int arg[]) {

is adjusted to pointer to type int. That is the following function declarations

void test(int arg[16]);
void test(int arg[]);
void test(int *arg);

are equivalent.

So inside the function there is used sizeof( int * ) that depending on the using platform usually equal to either 4 or 8.

You could declare the function in C++ like

void test(int ( &arg )[16]) {
    std::cout << "Testfn: " << sizeof(arg) << std::endl;
}

that is to declare the parameter as reference to the array and in this case you will get the expected result.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thanks alot! I had tried using test(int &arg[16]) but the compiler did not accept this so I canceled that possibility completely. Will accept in 9 minutes – Pieter De Clercq May 23 '17 at 19:32
1

If you use C++11 or higher, the std::array is what you need:

#include <iostream>
#include <array>

template<size_t N>
void test(const std::array<int, N>& arg) {
    std::cout << "Testfn: " << arg.size() << std::endl;
}

int main() {
    std::array<int, 16> int_arr;
    std::cout << "Length: " << int_arr.size() << std::endl;
    test(int_arr);
    std::cout << "Length again: " << int_arr.size() << std::endl;
}
Akira
  • 4,385
  • 3
  • 24
  • 46