What's the reason?

A

Amol

Consider the following.

#define UBOUND(x) sizeof(x)/sizeof(*x)

int main() {
int a[20] = {0};
cout << UBOUND(a) << endl; // prints 20

int* p = new int[20];

cout << UBOUND(p) << endl; // prints somthing different; on my
platform 1.
}


why is that so?
 
H

Hari

Amol je napisao:
Consider the following.

#define UBOUND(x) sizeof(x)/sizeof(*x)

int main() {
int a[20] = {0};
cout << UBOUND(a) << endl; // prints 20

int* p = new int[20];

cout << UBOUND(p) << endl; // prints somthing different; on my
platform 1.
}


why is that so?

int a[20] and int* p are different.

int a is array with 20 integers, and op is pointer to integer.
With litle calcs you can see:

sizeof(a) - size of array of 20 integers (probably 80)
sizeof(*a) - size of first element (probably 4)
sizeof(p) - size of pointer to int (probably 4)
sizeof(*p)- size of value of poitner to int (probably 4)

Best,
Zaharije Pasalic
 
N

Neelesh Bodas

Consider the following.

#define UBOUND(x) sizeof(x)/sizeof(*x)

int main() {
int a[20] = {0};
cout << UBOUND(a) << endl; // prints 20

UBOUND(a) gets replaced by sizeof(a)/sizeof(*a)
a being name of the array, sizeof(a) = size of the entire array =
sizeof(int)*20
Assuming sizeof(int) is m, we get sizeof(a) = 20*a
further, since *a is of type int, hence sizeof(*a) = sizeof(int) = a
Thus UBOUND(a) gets replaced by 20*a/a i.e. 20.
BTW this all happens at compile time, since sizeof is a compiler-time-
evaluated.

int* p = new int[20];

cout << UBOUND(p) << endl; // prints somthing different; on my
platform 1.

here UBOUND(p) = sizeof(p) / sizeof(*p).
sizeof(p) is sizeof(int*)
sizeof(*p) is sizeof(int)
so UBOUND(p) will be sizeof(int*)/sizeof(int). Depending on sizes of
int and int* on your machine, the answer might differ.

}

why is that so?

Fundamentally because sizeof() is a construct where a array name
does*not* get converted to a pointer to the first element.

-Neelesh
 
M

Mike Wahler

Amol said:
Consider the following.

#define UBOUND(x) sizeof(x)/sizeof(*x)

int main() {
int a[20] = {0};
cout << UBOUND(a) << endl; // prints 20

int* p = new int[20];

cout << UBOUND(p) << endl; // prints somthing different; on my
platform 1.
}


why is that so?

It appears that the size of a pointer-to-int and
the size of an int are the same on your system.

-Mike
 
J

James Kanze

Amol said:
Consider the following.
#define UBOUND(x) sizeof(x)/sizeof(*x)
int main() {
int a[20] = {0};
cout << UBOUND(a) << endl; // prints 20
int* p = new int[20];
cout << UBOUND(p) << endl; // prints somthing different; on my
platform 1.
}
why is that so?

As others have pointed out, it's because pointers aren't arrays.
Once you've got the pointer (returned from new), all
information concerning the size of the array is lost, unless
you've taken precautions before hand to explicitly save it.
This is one of the reasons why we almost never use C style
arrays in C++ (and never, never allocate them dynamically, where
you never have anything but the pointer).

If you want a safe way to determine the number of elements in a
C style array (which will fail to compile unless you have a C
style array):

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

So:

int main()
{
int a[ 20 ] ;
std::cout << size( a ) << std::endl ;
// prints 20
int* p = new int[ 20 ] ;
std::cout << size( p ) << std::endl ;
// doesn't compile.
return 0 ;
}

(Of course, the error messages when it doesn't compiler are
likely to be anything but readable.)
 
M

Marcus Kwok

James Kanze said:
If you want a safe way to determine the number of elements in a
C style array (which will fail to compile unless you have a C
style array):

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

Alf P. Steinbach wrote an article examining various ways to do this,
along with some of the pros and cons of each method:

http://home.no.net/dubjai/win32cpptut/special/pointers/array_size.doc.pdf


Ivan J. Johnson also has another approach:

http://www.ddj.com/dept/cpp/197800525
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top