What's the reason?

Discussion in 'C++' started by Amol, Jul 4, 2007.

  1. Amol

    Amol Guest

    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?
     
    Amol, Jul 4, 2007
    #1
    1. Advertising

  2. On Wed, 04 Jul 2007 10:20:50 -0000, Amol <> wrote:
    >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?


    See: http://c-faq.com/malloc/sizeof.html


    --
    Roland Pibinger
    "The best software is simple, elegant, and full of drama" - Grady Booch
     
    Roland Pibinger, Jul 4, 2007
    #2
    1. Advertising

  3. Amol

    Hari Guest

    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
     
    Hari, Jul 4, 2007
    #3
  4. On Jul 4, 3:20 pm, Amol <> wrote:
    > 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
     
    Neelesh Bodas, Jul 4, 2007
    #4
  5. Amol

    Mike Wahler Guest

    "Amol" <> wrote in message
    news:...
    > 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
     
    Mike Wahler, Jul 4, 2007
    #5
  6. Amol

    James Kanze Guest

    Amol wrote:
    > 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.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 5, 2007
    #6
  7. Amol

    Marcus Kwok Guest

    James Kanze <> wrote:
    > 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

    --
    Marcus Kwok
    Replace 'invalid' with 'net' to reply
     
    Marcus Kwok, Jul 5, 2007
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Weng Tianxiang

    Re: Compilation error reason???

    Weng Tianxiang, Jul 23, 2003, in forum: VHDL
    Replies:
    1
    Views:
    1,580
    Mike Treseler
    Jul 24, 2003
  2. Blake Versiga
    Replies:
    2
    Views:
    19,792
    Yan-Hong Huang[MSFT]
    Jul 9, 2003
  3. rl30
    Replies:
    1
    Views:
    632
    emachine
    Aug 15, 2003
  4. Frederik
    Replies:
    0
    Views:
    1,416
    Frederik
    Nov 25, 2003
  5. Frederik
    Replies:
    2
    Views:
    5,506
Loading...

Share This Page