Thread: Newbie question about 'sizeof' and arrays

  1. #1
    Registered User Sharke's Avatar
    Join Date
    Jun 2008
    Location
    NYC
    Posts
    303

    Newbie question about 'sizeof' and arrays

    I'm a little confused about sizeof, pointers and arrays. I'm starting with the information that an array name is really just a pointer to the first element in the array. So far so good.

    If I initialize an array like:

    Code:
    int mins[5] = {4, 6, 2, 7, 9};
    then "sizeof mins" gives me 20 - the total size of the array. But how is this so? If 'mins' is really just a pointer to the first element of an array, then shouldn't it give me 4 (assuming a 4-byte address)?

    Indeed, if I pass the pointer 'mins' to a function - e.g. 'sum(mins, 5)' - and that function header is:

    Code:
    int sum(int ar[], int n)
    then if I ask for 'sizeof ar' I'm given 4, since 'ar' is a pointer. But isn't 'mins' also a pointer?

    General sizeof/array/pointer confusion here! Help!

  2. #2
    Registered User
    Join Date
    Feb 2009
    Posts
    20
    This is proper behavior. I suspect the reason for the difference is that the array size of mins is known at compile time. What happens if you specify

    Code:
    int sum(int ar[5], int n)
    and take the sizeof ar?

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by Sharke View Post
    Code:
    int mins[5] = {4, 6, 2, 7, 9};
    then "sizeof mins" gives me 20 - the total size of the array. But how is this so?
    mins is an array of 5 int´s so the sizeof mins is 4*5 = 20 bytes, since an int is 4 bytes.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So sizeof doesn't care about evaluating anything, it just cares about the type. mins is of type int[5] -- i.e., an array of five integers -- so it has size 20 (probably). However, when mins is evaluated by itself somewhere, it decays to an int* -- hence if it passed to a function, say, the function only knows that what was passed to it is an int*; the information about it actually being an array is gone.

  5. #5
    Registered User Sharke's Avatar
    Join Date
    Jun 2008
    Location
    NYC
    Posts
    303
    Quote Originally Posted by drunken_scot View Post
    What happens if you specify

    Code:
    int sum(int ar[5], int n)
    and take the sizeof ar?
    I'm given the same value no matter what value I substitute for '5.'

    Quote Originally Posted by tabstop View Post
    So sizeof doesn't care about evaluating anything, it just cares about the type. mins is of type int[5] -- i.e., an array of five integers -- so it has size 20 (probably).
    This is what confuses me. I was under the impression that mins was of type "pointer to int" - i.e., a pointer to the first value of the array mins[], which is an int. I understand that the total size of the array in this case works out as 20 bytes, but not why sizeof mins gives that answer.

    The confusion started because the book I'm working from just told me this a couple of pages ago:

    .....an array name is also the address of the first element of the array. That is, if 'flinzy' is an array, the following is true:

    Code:
    flinzy == &flinzy[0];
    If 'flinzy' is an address, i.e. an int*, then shouldn't 'sizeof flinzy' return 4?

    Quote Originally Posted by tabstop View Post
    However, when mins is evaluated by itself somewhere, it decays to an int* -- hence if it passed to a function, say, the function only knows that what was passed to it is an int*; the information about it actually being an array is gone.
    I suppose I can hold this information in my head and accept it, but I still don't understand why sizeof mins gives the full size of the array, since mins is a pointer which holds an address. It just seems inconsistent with what I've held to be true so far.

  6. #6
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    an array name is also the address of the first element of the array.
    The book you got this information from is wrong. This is a very common misconception, though, and an understandable one. The thing is, almost all of the time, you can't tell the difference between an array and a pointer. You just happened to discover that sizeof is one of the few times that you can tell the difference. The only other time that really matters is with the & (address-of) operator. In other instances, you can treat an array name like a pointer, but you simply have to remember that it's not truly a pointer; it just gets converted to one in most cases.

    As for the & operator:
    Code:
    void f(int **p)
    {
    }
    int main(void)
    {
      int *p, a[5];
      f(&p); /* OK */
      f(&a); /* Not OK!  Since a is not a pointer, &a is not a pointer-to-pointer */
      return 0;
    }
    It's just one of those C rules you have to remember.

  7. #7
    Registered User Sharke's Avatar
    Join Date
    Jun 2008
    Location
    NYC
    Posts
    303
    The book I got it from was Prata's "C Primer Plus," 5th edition. Seems like a sloppy error for him to make! I guess I'll just plod on with this new knowledge feeling ever so slightly uneasy...though of course it'll probably click into place in time like everything else.

    Thanks for all the replies.

  8. #8
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by Sharke View Post
    I suppose I can hold this information in my head and accept it, but I still don't understand why sizeof mins gives the full size of the array, since mins is a pointer which holds an address...
    Frankly I too haven't been able to find a satisfactory answer. The "sizeof operator" section given in Appendix A of K&R's ANSI C book says that:

    "when applied to an array, the result is the total number of bytes in the array ..."

    Don't know if that helps or not?

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    Frankly I too haven't been able to find a satisfactory answer.
    Then read tabstop's post #4 and cas' post #6.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    Then read tabstop's post #4 and cas' post #6.
    What I have come across in different books, manuals etc. is that is if the array is:
    Code:
    int mins[5];  /* the type of mins is "pointer to ..." */

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC View Post
    What I have come across in different books, manuals etc. is that is if the array is:
    Code:
    int mins[5];  /* the type of mins is "pointer to ..." */
    Then those "different books, manuals etc" are wrong. From the 1999 edition of the C standard, section 6.3.2.1 paragraph 3:
    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 and is not an lvalue.
    Section 6.7.5.2 on "array declarators" more directly contradicts the material that you have read, but I think it is harder to make sense of for those less familiar with "standardese".
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Isn't that exactly what I said in my posts, since those statements were extracted from the Appendix given in the back of K&R's ANSI C.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    Isn't that exactly what I said in my posts, since those statements were extracted from the Appendix given in the back of K&R's ANSI C.
    It is not. The additional part concerns the fact that array types exist, and not just pointer types. If you already know this, then what are you not satisfied about?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Cool beans! that's what I said in post #8 that the name of the array mins is of the type pointer to ... but its size is the total number of bytes in it. I accept what the Gods (K&R) have created but was looking for justification behind that rule.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    Cool beans!


    Quote Originally Posted by itCbitC
    that's what I said in post #8 that the name of the array mins is of the type pointer to
    But that is wrong: an array is an array, not a pointer. Under most circumstances, an array is converted to a pointer to its first element, but its type remains "array of type", not "pointer to type". This is what tabstop and cas have stated earlier in this thread.

    Consequently, the sizeof rule makes sense: you are asking for the size of an array, not the size of a pointer.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bit arrays with STL containers
    By Mario F. in forum C++ Programming
    Replies: 23
    Last Post: 07-03-2007, 09:50 AM
  2. arrays dimensioning: malloc and sizeof
    By c programmer in forum C Programming
    Replies: 10
    Last Post: 03-27-2007, 12:03 PM
  3. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  4. questions about arrays
    By laasunde in forum C++ Programming
    Replies: 3
    Last Post: 08-14-2003, 05:53 AM
  5. sizeof on arrays
    By sanu in forum C++ Programming
    Replies: 10
    Last Post: 06-28-2002, 10:10 AM