Size of an array C++ [duplicate]

2020-04-02 08:49发布

问题:

This question already has answers here:
Closed 7 years ago.

Possible Duplicate:
Sizeof array passed as parameter

I was wondering why the output of the following code is 1 and 9. Is that because of undeclared array in function size? How can I separate "size of array" to a function?

#include "stdafx.h"
#include <iostream>
using namespace std;

int size(int a[])
{
    return sizeof a/sizeof a[0];
}

int main()
{   
    int a[] = {5,2,4,7,1,8,9,10,6};
    cout << size(a) << endl;
    cout << sizeof a/sizeof a[0] << endl;
    system("pause");
    return 0;
}

回答1:

When you write size(a) then you're passing a pointer and not an array. Since the size of a pointer and an int is 4 or 8 (depending on ABI), you get sizeof(int *)/sizeof int (4/4=1 for 32-bit machines and 8/4=2 for 64-bit ones) which is 1 or 2.

In C++ when pass an array as an argument to a function, actually you're passing a pointer to an array.



回答2:

Maroun85 answer is correct. This is not obvious but a in int size(int a[]) is a pointer.

But why don't you do it the c++ way. Using std::vectors

std::vector<int> a = {5,2,4,7,1,8,9,10,6};
cout << a.size() << endl;

no tricks here

-- edit

If your compiler does not support c++11. You can do:

std::vector<int> a;
a.push(5);
a.push(2);
...
cout << a.size() << endl;


回答3:

Your size() function cannot work like you want it to because when you pass an array to a function, the array decays to a pointer to its first element. Your a decays to a int* and sizeof operator on a pointer returns the size of the pointer, not the array. Consider using a std::vector<int> instead as this will allow you to retrieve the size of the vector each time you pass it to the function.



回答4:

When passing arrays to functions, they decay to pointers. So, your size() function is equivalent to:

int size(int* a)
{
    return sizeof a/sizeof a[0];
}

And sizeof a is the size of a pointer, which is the same as the size of an int here, hence the output.



回答5:

sizeof is evaluated at compile time, not at runtime. The compiler does not analyse what you pass to function size, but rather treats the function parameter as a pointer. Thus in your function size the result of sizeof a is the size of a pointer to an int, which is, by chance, equal to the size of an int on your system.



回答6:

Remember that array are always passed by pointer.

So in the function a is a pointer to int, and (for 32bit-intergers) the size of a pointer to int is the same of the size of an int.



回答7:

The best explanation why your solution does not work is in Maroun's answer.

About the second part of the question ("how can it be done?"), you can do this with a template function:

template <typename T, size_t n> const size_t size(const T (&)[n]) { return n; }

Of course, this works only if the size of the array is constant (constant, as seen by the compiler), but it can only ever work in this case anyway -- an array does not store its size anywhere, so if it's not a known compile-time constant, there is no way to know it.

If you need this to work with arrays that are not compile-time constants (say, something you allocate with operator new[], or using a non-standard compiler extension), you need to explicitly store the size somewhere.

(Incidentially, my above statement is technically wrong, indeed the allocation size is usually stored, but this is an implementation detail which you cannot and should not depend on.)