简体   繁体   中英

problem with sizeof operator

As i want to find array size dynamically in function, i used sizeof operator. But i got some unexpected result. here is one demo program to show you, what i want to do.

//------------------------------------------------------------------------------------------
#include <iostream>

void getSize(int *S1){

    int S_size = sizeof S1/sizeof(int);
    std::cout<<"array size(in function):"<<S_size<<std::endl;
}

int main(){

    int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
    getSize(S);
    std::cout<<"array size:"<<sizeof S/sizeof(int)<<std::endl;
    return 0;
}
//------------------------------------------------------------------------------------------

compilation command : g++ demo1.cc -o demo1 {fedora 12}

output:

array size(in function):2
array size:19

please explain ,why this is happening. what can be done to solve this problem.

void getSize(int *S1)

When you pass an array to this function, it decays to pointer type, so sizeof operator will return the size of pointer.

However, you define your function as,

template<int N>
void getSize(int (&S1)[N])
{
   //N is the size of array
   int S_size1 = N;
   int S_size2 = sizeof(S1)/sizeof(int); //would be equal to N!!
   std::cout<<"array size(in function):"<<S_size1<<std::endl;
   std::cout<<"array size(in function):"<<S_size2<<std::endl;
}

int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
getSize(S); //same as before

then you can have the size of array, in the function!

See the demonstration yourself here : http://www.ideone.com/iGXNU

Inside getSize() , you're getting size of pointer, which is 8 bytes (since you're probably running 64-bit OS). In main() , you're getting size of array.

If you want to know array size, pass result of sizeof(S) as additional argument to getSize() .

More alternatives would be using some container (like std::vector ) or turning function into template function, as Nawaz proposed.

you are getting the size of the pointer to the array. If you want the size of the array you have to multiply the number of elements by the size of each element.

You will have to pass the size of the array to the function.

Since you are only passing a pointer to the first element in the array, your function has no information on its actual size.

void getSize(int *S1, size_t size)
{
    int S_Size = sizeof(*S1) * size;
}

This is redundant though, if you think about it :D

S is an int * , a pointer to an integer, which is a memory address, which is on your machine twice the size of an integer.

If you want the size of the array (Ie, the number of elements), you can't get that directly in pure C. But since this is a c++ question, there is a way: use a vector , which has a size() method.

Actually, this isn't quite true: within the function that you declare S (and only if it's explicitly initialized at compile time as you do in your example -- even new int[19] doesn't work), the sizeof operator actually does get the correct answer, which is why c++ allows you to do this:

int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
vector<int> v(S, S + sizeof(S) / sizeof(int) );

and then you can use v.size() (see these docs ).

The template version by Nawaz elsewhere is another excellent suggestion which forces the compiler into carrying the full information about the construction of the c++ array around (again, note that this is all known at compile time , which is why you can be explicit about the size in the argument).

To prevent this type of accidental misuse of sizeof, you can define a function which only works on arrays:

template<class T, int N>
int array_size(T (&)[N]) {
  return N;
}

If you use this in your code, you'll see a compiler error when applied to S1, as it is not an array. Plus, it's shorter and a bit more explicit than sizeof array / sizeof array[0] (using the size of the first item means you don't have to repeat the array type).

This also already exists in Boost in a more general form (accepting anything with a size method, such as std::vector).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM