sizeof and passing pointer

Discussion in 'C Programming' started by jason, Oct 21, 2007.

  1. jason

    jason Guest

    Hello,

    I'm a beginning C programmer and I have a question regarding arrays and
    finding the number of entries present within an array.

    If I pass an array of structures to a function, then suddenly I can't use
    sizeof(array) / sizeof(array[0]) anymore within that function ?

    Help - What point am I missing ?

    To show an example below. The commented out code that works where as the
    exact same code, only wrapped in a function does not work ?

    Thank you...

    #include <stdio.h>

    typedef struct {
    char *name;
    char *cat;
    char *desc;
    int wday;
    int dur;
    } entry_t;

    entry_t entries[] = {
    { "dummy", "todo", "explanation", 1, 20 },
    { "not", "bla", "foobar", 1, 10 },
    { "check", "nowhere", "for something", 1, 20 }
    };

    void task_dump(entry_t *);

    int main(int argc, char *argv[]) {
    /*
    int i = 0;
    int max = 0;

    max = sizeof(entries) / sizeof(entries[0]);
    for(i = 0; i < max; i++) {
    printf(" -- %02d\n", i);
    printf(" name : %s\n", entries.name);
    printf(" catagory : %s\n", entries.cat);
    printf(" descript : %s\n", entries.desc);
    printf(" weekday : %d\n", entries.wday);
    printf(" duration : %d\n", entries.dur);
    }
    */

    task_dump(entries);

    return 0;
    }

    void task_dump(entry_t *data) {
    int i = 0;
    int max = 0;

    /* this doesn't work ? */
    max = sizeof(data) / sizeof(data[0]);
    for(i = 0; i < max; i++) {
    printf(" -- %02d\n", i);
    printf(" name : %s\n", data.name);
    printf(" catagory : %s\n", data.cat);
    printf(" descript : %s\n", data.desc);
    printf(" weekday : %d\n", data.wday);
    printf(" duration : %d\n", data.dur);
    }

    return;
    }
     
    jason, Oct 21, 2007
    #1
    1. Advertising

  2. "jason" <> wrote in message
    > Hello,
    >
    > I'm a beginning C programmer and I have a question regarding arrays and
    > finding the number of entries present within an array.
    >

    Arrays decay to pointers when you pass them to functions. So you need to
    pass in the number of elements as a separate parameter.

    When you start writing real programs you will find that the number of cases
    where you know an array's size at compile time is quite few. Usually the
    size is determined by the data the user inputs, so you must allocate the
    space with malloc().

    --
    Free games and programming goodies.
    http://www.personal.leeds.ac.uk/~bgy1mm
     
    Malcolm McLean, Oct 21, 2007
    #2
    1. Advertising

  3. >I'm a beginning C programmer and I have a question regarding arrays and
    >finding the number of entries present within an array.
    >
    >If I pass an array of structures to a function, then suddenly I can't use
    >sizeof(array) / sizeof(array[0]) anymore within that function ?


    You can pass a *pointer* to an array of structures to a function.
    It may look like you're passing the array, and the syntax makes it
    easy to be fooled, but you're not. The size of the array you passed
    isn't passed with the pointer to the array, so if you want the size,
    you have to do it manually (e.g. pass it as another argument to the
    function).

    >Help - What point am I missing ?


    sizeof applied to a pointer does not give the size of what it points
    at, except occasionally by accident. It gives the size of the pointer.
     
    Gordon Burditt, Oct 21, 2007
    #3
  4. jason

    jason Guest

    On Sun, 21 Oct 2007 18:36:09 +0100, Malcolm McLean wrote:

    > "jason" <> wrote in message
    >> Hello,
    >>
    >> I'm a beginning C programmer and I have a question regarding arrays and
    >> finding the number of entries present within an array.
    >>

    > Arrays decay to pointers when you pass them to functions. So you need to
    > pass in the number of elements as a separate parameter.
    >
    > When you start writing real programs you will find that the number of
    > cases where you know an array's size at compile time is quite few.
    > Usually the size is determined by the data the user inputs, so you must
    > allocate the space with malloc().


    Ok thankx for that !

    But just to make sure; what does `decay' exactly mean in this case ? And
    what properties of the pointer, when passed to a function actually
    change ?

    Thank you.

    Jason.
     
    jason, Oct 21, 2007
    #4
  5. "jason" <> wrote in message news:471b8fa0$0$14414
    > But just to make sure; what does `decay' exactly mean in this case ? And
    > what properties of the pointer, when passed to a function actually
    > change ?
    >


    int main(void)
    {
    int array[10] = {1,2,3,4,5,6,7,8,910};

    printf("array is %d bytes\n", (int) sizeof(array));
    foo(array, 10);
    }

    void foo(int *ptr, int N)
    {
    int i;

    printf("pointer is %d\n", (int) sizeof(ptr))'
    /* treat as array */
    for(i=0;i<N;i++)
    print("%d\n", ptr);
    /* treat as pointer */
    for(i=0;i<N;i++)
    printf("%d\n", *ptr++);
    }

    in main your array is an array. When you pass it to foo it converts -
    decays - into a pointer. arrays are very nearly, but not quite, constant
    pointers. You can use the brackets notation on either an array or a pointer.
    However you can also increment a pointer. Whilst sizeof(ptr) gives the size
    of the memory item needed to hold the address, usually 4 bytes, whilst
    sizeof(array) gives the size of the data in the array, probably either 20 or
    40 bytes.

    --
    Free games and programming goodies.
    http://www.personal.leeds.ac.uk/~bgy1mm
     
    Malcolm McLean, Oct 21, 2007
    #5
  6. jason <> writes:

    > On Sun, 21 Oct 2007 18:36:09 +0100, Malcolm McLean wrote:
    >
    >> "jason" <> wrote in message
    >>> Hello,
    >>>
    >>> I'm a beginning C programmer and I have a question regarding arrays and
    >>> finding the number of entries present within an array.
    >>>

    >> Arrays decay to pointers when you pass them to functions. So you need to
    >> pass in the number of elements as a separate parameter.
    >>
    >> When you start writing real programs you will find that the number of
    >> cases where you know an array's size at compile time is quite few.
    >> Usually the size is determined by the data the user inputs, so you must
    >> allocate the space with malloc().

    >
    > Ok thankx for that !
    >
    > But just to make sure; what does `decay' exactly mean in this case ? And
    > what properties of the pointer, when passed to a function actually
    > change ?


    What is going on comes from this wording the C standard:

    Except when it is the operand of the sizeof operator or the unary &
    operator, or is a string literal used to initialize an array, an
    expression that has type ‘‘array of type’’ is converted to an
    expression with type ‘‘pointer to type’’ that points to the initial
    element of the array object

    so, in fact, almost every use of an array involves this conversion.
    Writing the name of an array in a function call is only one example of
    the general rule.

    Your example of determining the number of elements:

    sizeof table / sizeof *table

    involves one of each. 'table' is not converted in the numerator
    (because it is the operand of sizeof) but it is in the denominator.

    --
    Ben.
     
    Ben Bacarisse, Oct 21, 2007
    #6
  7. jason <> writes:
    [...]
    > But just to make sure; what does `decay' exactly mean in this case ? And
    > what properties of the pointer, when passed to a function actually
    > change ?


    It's really not about argument passing.

    An expression of array type is implicitly converted to a pointer to
    the first element of the array *unless* it's the operand of a unary
    "&" or "sizeof" operator, or it's a string literal used in an
    initializer for an array.

    All this and more is explained in section 6 of the comp.lang.c FAQ,
    <http://www.c-faq.com>.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 21, 2007
    #7
  8. jason

    jason Guest

    Re: sizeof and passing pointer [solved]

    People,

    Thank you so much for all the great explanations. I now understand now
    the actual problem. [In such that's not really a problem :)]

    Thankx..

    Jason




    On Sun, 21 Oct 2007 19:12:25 +0100, Malcolm McLean wrote:
    > "jason" <> wrote in message news:471b8fa0$0$14414
    >> But just to make sure; what does `decay' exactly mean in this case ?
    >> And what properties of the pointer, when passed to a function actually
    >> change ?
    >>
    >>

    > int main(void)
    > {
    > int array[10] = {1,2,3,4,5,6,7,8,910};
    >
    > printf("array is %d bytes\n", (int) sizeof(array)); foo(array, 10);
    > }
    >
    > void foo(int *ptr, int N)
    > {
    > int i;
    >
    > printf("pointer is %d\n", (int) sizeof(ptr))' /* treat as array */
    > for(i=0;i<N;i++)
    > print("%d\n", ptr);
    > /* treat as pointer */
    > for(i=0;i<N;i++)
    > printf("%d\n", *ptr++);
    > }
    >
    > in main your array is an array. When you pass it to foo it converts -
    > decays - into a pointer. arrays are very nearly, but not quite, constant
    > pointers. You can use the brackets notation on either an array or a
    > pointer. However you can also increment a pointer. Whilst sizeof(ptr)
    > gives the size of the memory item needed to hold the address, usually 4
    > bytes, whilst sizeof(array) gives the size of the data in the array,
    > probably either 20 or 40 bytes.
     
    jason, Oct 21, 2007
    #8
  9. "Malcolm McLean" <> writes:
    [...]
    > in main your array is an array.


    Right.

    > When you pass it to foo it converts -
    > decays - into a pointer.


    Not quite. You can't actually pass an array as an argument. What you
    can do is pass the result of the conversion as an argument.

    > arrays are very nearly, but not quite, constant
    > pointers.


    This is extremely misleading.

    Arrays are arrays. Pointers are pointers. Evaluating an array
    expression *in most contexts* causes it to be converted to a pointer.

    An array is not a pointer. An array expression may be *converted* to
    a pointer value.

    Again, see section 6 of the comp.lang.c FAQ.

    > You can use the brackets notation on either an array or a pointer.


    Right, but that's only because the array operand is converted to a
    pointer. The "[]" operator requires a pointer operand and an integer
    operand.

    > However you can also increment a pointer. Whilst sizeof(ptr) gives the size
    > of the memory item needed to hold the address, usually 4 bytes, whilst
    > sizeof(array) gives the size of the data in the array, probably either 20 or
    > 40 bytes.


    Right; that's because sizeof is one of the contexts in which the
    conversion doesn't take place.

    There's more than enough confusion about the relationship between
    arrays and pointers. Please don't add to it.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 21, 2007
    #9
  10. Keith Thompson said:

    > "Malcolm McLean" <> writes:
    > [...]
    >> in main your array is an array.

    >
    > Right.
    >
    >> When you pass it to foo it converts -
    >> decays - into a pointer.

    >
    > Not quite. You can't actually pass an array as an argument.


    You can, however, use an array name in an argument expression.

    > What you can do is pass the result of the conversion as an argument.


    Yes, argument expressions are evaluated. The results of those evaluations
    can reasonably be called parameters.

    <snip>

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Oct 21, 2007
    #10
  11. On Oct 21, 10:42 am, jason <> wrote:
    > On Sun, 21 Oct 2007 18:36:09 +0100, Malcolm McLean wrote:
    > > "jason" <> wrote in message
    > >> Hello,

    >
    > >> I'm a beginning C programmer and I have a question regarding arrays and
    > >> finding the number of entries present within an array.

    >
    > > Arrays decay to pointers when you pass them to functions. So you need to
    > > pass in the number of elements as a separate parameter.

    >
    > > When you start writing real programs you will find that the number of
    > > cases where you know an array's size at compile time is quite few.
    > > Usually the size is determined by the data the user inputs, so you must
    > > allocate the space with malloc().

    >
    > Ok thankx for that !
    >
    > But just to make sure; what does `decay' exactly mean in this case ? And
    > what properties of the pointer, when passed to a function actually
    > change ?


    The phrase "decays to a pointer" is verbal shorthand for the way the C
    language evaluates expressions of type array. With three exceptions
    mentioned later, an expression of type array is converted to the
    address of the first element with type pointer to element type. For
    some type T, if you define an array of N objects of type T, as in
    T x[N];
    and then pass the array to a function, as in
    func(x);
    it is exactly equivalent to
    func(&x[0]);

    The three exceptions are:
    when the operand of the sizeof operator.
    when the operand of the & operator.
    when a string literal is used as the initialization value in the
    definition of an array of char.

    When the pointer value is passed to the function, none of its
    "properties" are changed. The point being made is that it is a
    pointer value, not an array value, that is passed. Therefore,
    properties unique to the array (such as number of elements) are what
    is lost. Properties shared by the array and the pointer (such as
    address of the array and the type of its elements) are preserved.
     
    Barry Schwarz, Oct 21, 2007
    #11
  12. jason

    Default User Guest

    Re: sizeof and passing pointer [solved] - TPA

    jason wrote:

    >
    > People,


    Please don't top-post. Your replies belong following or interspersed
    with properly trimmed quotes. See the majority of other posts in the
    newsgroup, or:
    <http://www.caliburn.nl/topposting.html>
     
    Default User, Oct 21, 2007
    #12
  13. jason

    Ben Pfaff Guest

    Richard Heathfield <> writes:

    > Yes, argument expressions are evaluated. The results of those evaluations
    > can reasonably be called parameters.


    That is close to the definitions given for "argument" and
    "parameter" in the standard: an argument is an expression and a
    parameter is an object.

    I'm not certain that this is relevant anymore to the OP's
    question.
    --
    Ben Pfaff
    http://benpfaff.org
     
    Ben Pfaff, Oct 22, 2007
    #13
  14. Ben Pfaff <> writes:
    > Richard Heathfield <> writes:
    >> Yes, argument expressions are evaluated. The results of those evaluations
    >> can reasonably be called parameters.

    >
    > That is close to the definitions given for "argument" and
    > "parameter" in the standard: an argument is an expression and a
    > parameter is an object.


    Specifically, an argument is one of the comma-separated expressions
    between the parentheses in a function call, and a parameter is the
    object, local to the called function, to which the result of
    evaluating the argument is assigned.

    If the argument expression is an array name, the result of evaluating
    that expression is a pointer value, which is assigned to the parameter
    object.

    > I'm not certain that this is relevant anymore to the OP's
    > question.


    Nor am I.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 22, 2007
    #14
  15. jason

    MisterE Guest

    "jason" <> wrote in message
    news:471b88b0$0$14414$4all.nl...
    > Hello,
    >
    > I'm a beginning C programmer and I have a question regarding arrays and
    > finding the number of entries present within an array.
    >
    > If I pass an array of structures to a function, then suddenly I can't use
    > sizeof(array) / sizeof(array[0]) anymore within that function ?
    >
    > Help - What point am I missing ?
    >
    > To show an example below. The commented out code that works where as the
    > exact same code, only wrapped in a function does not work ?
    >
    > Thank you...


    One of the best things to learn now (so it will help later) is that an array
    is really just a pointer, its pointers to space set aside for you to use. If
    you pass an array to a function, you are really only passing a pointer,
    sizeof(array) is something you want to learn to never use, infact I find it
    hard to believe it is even part of c standard.
     
    MisterE, Oct 22, 2007
    #15
  16. Keith Thompson said:

    > Ben Pfaff <> writes:

    <snip>
    >> I'm not certain that this is relevant anymore to the OP's
    >> question.

    >
    > Nor am I.


    If we only ever said stuff that was relevant to OPs' questions, the traffic
    on this group would drop by about 80-90%. That wouldn't necessarily be a
    Good Thing, because much interesting and useful C-related discussion
    emerges from such topic-drifting.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Oct 22, 2007
    #16
  17. jason

    Richard Bos Guest

    "MisterE" <> wrote:

    > One of the best things to learn now (so it will help later) is that an array
    > is really just a pointer, its pointers to space set aside for you to use.


    No, that's one of the worst things to learn about C. It's a common
    misconception, and one which has lead many amateur programmers into
    error. However, any professional, well-informed C programmer will tell
    you that it is false. See, for example, the first questions in section 6
    of the c.l.c FAQ: <http://c-faq.com/aryptr/index.html>.

    Richard
     
    Richard Bos, Oct 22, 2007
    #17
  18. "MisterE" <> writes:
    [...]
    > One of the best things to learn now (so it will help later) is that an array
    > is really just a pointer, its pointers to space set aside for you to use. If
    > you pass an array to a function, you are really only passing a pointer,
    > sizeof(array) is something you want to learn to never use, infact I find it
    > hard to believe it is even part of c standard.


    No.

    Please *unlear* this. An array is not a pointer. Arrays are arrays;
    pointer are pointers. sizeof(array) yields the size *of the array*,
    and can be extremely useful.

    Read section 6 of the comp.lang.c FAQ, <http://www.c-faq.com>, and the
    other responses in this thread.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 22, 2007
    #18
  19. "MisterE" <> a écrit dans le message de news:
    471c6981$0$14825$...
    >
    > "jason" <> wrote in message
    > news:471b88b0$0$14414$4all.nl...
    >> Hello,
    >>
    >> I'm a beginning C programmer and I have a question regarding arrays and
    >> finding the number of entries present within an array.
    >>
    >> If I pass an array of structures to a function, then suddenly I can't use
    >> sizeof(array) / sizeof(array[0]) anymore within that function ?
    >>
    >> Help - What point am I missing ?
    >>
    >> To show an example below. The commented out code that works where as the
    >> exact same code, only wrapped in a function does not work ?
    >>
    >> Thank you...

    >
    > One of the best things to learn now (so it will help later) is that an
    > array is really just a pointer, its pointers to space set aside for you to
    > use. If you pass an array to a function, you are really only passing a
    > pointer, sizeof(array) is something you want to learn to never use, infact
    > I find it hard to believe it is even part of c standard.


    Please NO!

    An array is not a pointer!
    An array *has* an address, a pointer *is* an address.
    When passing an array to a function, only its address is passed, which is
    indistinguishible from the value of a pointer to the first element of the
    array.

    sizeof(array) is very useful, but error prone because it is difficult to
    always ensure ``array'' is indeed an array, not just a pointer with a
    confusing name.

    --
    Chqrlie.
     
    Charlie Gordon, Oct 22, 2007
    #19
  20. jason

    CBFalconer Guest

    Richard Heathfield wrote:
    > Keith Thompson said:
    >> "Malcolm McLean" <> writes:
    >> [...]
    >>> in main your array is an array.

    >>
    >>> When you pass it to foo it converts - decays - into a pointer.

    >>
    >> Not quite. You can't actually pass an array as an argument.

    >
    > You can, however, use an array name in an argument expression.
    >
    >> What you can do is pass the result of the conversion as an
    >> argument.

    >
    > Yes, argument expressions are evaluated. The results of those
    > evaluations can reasonably be called parameters.


    What is lost in passing an array is the size of the array. This is
    due to conversion to a pointer to the first item. Why shouldn't a
    later C version adopt the convention that:

    void foo(T array[SIZE]) {
    /* foo code */
    }

    makes array an array[SIZE] (fixed), and thus replaces the missing
    size value. This might be more understandable to noobs than
    passing a separate size. That parameter declaration would cause
    such expressions as "sizeof(array)" to return "SIZE *
    sizeof(*(&T))", and the & in &T would be simply absorbed.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Oct 23, 2007
    #20
    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. Derek
    Replies:
    7
    Views:
    24,395
    Ron Natalie
    Oct 14, 2004
  2. Trevor

    sizeof(str) or sizeof(str) - 1 ?

    Trevor, Apr 3, 2004, in forum: C Programming
    Replies:
    9
    Views:
    656
    CBFalconer
    Apr 10, 2004
  3. jimjim
    Replies:
    16
    Views:
    861
    Jordan Abel
    Mar 28, 2006
  4. Alex Vinokur
    Replies:
    7
    Views:
    511
    Clark S. Cox III
    Aug 14, 2006
  5. Alex Vinokur

    sizeof (size_t) and sizeof (pointer)

    Alex Vinokur, Nov 12, 2007, in forum: C++
    Replies:
    19
    Views:
    808
    Ben Rudiak-Gould
    Nov 30, 2007
Loading...

Share This Page