Newbie question about 'sizeof' and arrays

Printable View

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 02-26-2009
Sharke
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!
• 02-26-2009
drunken_scot
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?
• 02-26-2009
Subsonics
Quote:

Originally Posted by Sharke
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.
• 02-26-2009
tabstop
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.
• 02-27-2009
Sharke
Quote:

Originally Posted by drunken_scot
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
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:

Quote:

.....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
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.
• 02-27-2009
cas
Quote:

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.
• 02-27-2009
Sharke
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.
• 02-27-2009
itCbitC
Quote:

Originally Posted by Sharke
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?
• 02-27-2009
laserlight
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.
• 02-27-2009
itCbitC
Quote:

Originally Posted by laserlight
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 ..." */`
• 02-27-2009
laserlight
Quote:

Originally Posted by itCbitC
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:
Quote:

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".
• 02-27-2009
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.
• 02-27-2009
laserlight
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?
• 02-27-2009
itCbitC
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.
• 02-27-2009
laserlight
Quote:

Originally Posted by itCbitC
Cool beans!

:cool:

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.
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last