views:

134

answers:

8

If I write

int main()
{
    int a[100] = {1,2,3,4,};
    cout<<sizeof(a)/sizeof(a[0])<<endl; //a is a pointer to the first elem of array, 
                                        //isn't it
    return 0;
}

I get 400!

If I write

void func(int *a);

int main()
{
    int a[100] = {1,2,3,4,};
    func(a);
    return 0;
}

void func(int *a)
{
     cout<<sizeof(a)/sizeof(a[0])<<endl; //a is a pointer to the first elem of array
}

Then I get 1!

So why function does not know the array size?

+4  A: 

Arrays decay to pointers when passed to functions, so all you will get is the size of the pointer.

Paul R
Arrays decay to pointers only when the passing format *requests* them to decay, i.e. if the corresponding parameter is declared as a pointer (as in this case). If the parameter were declared as a reference to an array, the decay wouldn't take place.
AndreyT
@AndreyT: who said anything about references ? If your function is `void func(int a[])` then `a` will still have decayed to a pointer.
Paul R
A: 

No. You are wrong.

If I run your second part of code, it gives 1 on my computer. It's not 400.

#include <iostream>

void func(int *a);

using namespace std;

int main()
{
    int a[100] = {1,2,3,4,};
    func(a);
    return 0;
}

void func(int *a)
{
     cout<<sizeof(a)/sizeof(a[0])<<endl;
}

Produces

1
SiLent SoNG
-1 this is exactly what he saids :)
Vicente Botet Escriba
In the original post he said he got 400.
SiLent SoNG
A: 

You get 400 the first time because you are passing only sizeof(a), not sizeof(a)/sizeof(a[0]), to cout. You need to wrap that calculation with parenthesis to get the correct value outputted, ie:

cout << (sizeof(a)/sizeof(a[0])) << endl;

For the second time, you should be getting 2, 4, or 8 (depending on architecture), definately not 400, since you are essentially outputting this:

cout << sizeof(int*) << endl;

Where the size of a generic pointer is always a fixed value.

Remy Lebeau - TeamB
+1  A: 

sizeof returns the size of the type. In the second example, func( int *a ), a is a pointer and sizeof will report it as such. Even if you did func( int a[100] ), a would be a pointer. If you want the size of the array in func, you must pass it as an extra argument.

drawnonward
A: 

A pointer is a pointer. That means, it simply points to memory, and that's all about it. Creating a pointer to an array (which usually means a pointer to the first element of the array, but not necessarily) is still only a pointer to some memory location. As a memory address is simply a memory address there is also no way for the pointer to know that the memory it is pointing to originally was an array, or how long that array was.

It's simply how pointers work. They point to memory, and that's all.

bluebrother
A: 

This isn't working because sizeof is calculated at compile-time. The function has no information about the size of its parameter (it only knows that it points to a memory address).

Consider using an STL vector instead, or passing in array sizes as parameters to functions.

This was answered by Marcel Guzman in http://stackoverflow.com/questions/720077/calculating-size-of-an-array!

Narek
This is the first time I've seen the accepted answer at -1.
tadman
+1  A: 

When passing your array as a parameter to a function taking a pointer, the array decays as a pointer.

void bar(int *a)
{
    std::cout << sizeof(a) << std::endl; // outputs "4" (on a 32 bit compiler)
}

void foo()
{
    int a[100] ;
    std::cout << sizeof(a) << std::endl; // outputs "400" (on a 32 bit compiler)
    bar(a);
}

So perhaps the solution is to provide a correct function taking a reference to an array as a parameter :

template <size_t T_Size>
void bar(int (&a)[T_Size])
{
    std::cout << T_Size << std::endl;    // outputs "100" (on ALL compilers)
    std::cout << sizeof(a) << std::endl; // outputs "400" (on a 32 bit compiler)
}

void foo()
{
    int a[100] ;
    std::cout << sizeof(a) << std::endl; // outputs "400" (on a 32 bit compiler)
    bar(a);
}

Of course, the function must be templated.

paercebal
A: 

The function does not know the array size in your example because you took explicit steps to convert your array to pointer type, thus completely stripping the function parameter of its original array nature. Once again, you yourself took deliberate steps to make sure that the function does not know the size of the array. Under these circumstances, it is rather strange to see you ask the question about why the function doesn't know the array size.

If you what the function to receive its argument as an array, you have to pass it as an array, not as a mere pointer, and declare the corresponding function parameter accordingly. Arrays in C++ cannot be passed "by value", which means that you'll have to pass it "by reference", as one possibility

void func(int (&a)[100])
{
  cout << sizeof a / sizeof a[0] << endl;
}
AndreyT