1

If I have:

int a[] = {1,2,3}; int len = sizeof(a) / sizeof(int); 

I get 3, and I don't understand why.

They always taught me that an array is a pointer, doesn't store its length, but only the pointer to the first element.

Can someone explain this to me in a better way?

5
  • 7
    Whoever taught you that an array is a pointer was very wrong, as you can see from this example. Just ignore it. I'm not sure what there is to explain. sizeof(a) gives you the size of the array in bytes. Commented Mar 9, 2016 at 21:29
  • I guess my statement was an oversimplification of what i intended to say. Not wrong, but oversimplified. Point taken. Will remove comments Commented Mar 9, 2016 at 21:44
  • @UnderDog Or just plain wrong. At least, it is a mental model that causes so much confusion as to be counter-productive. Commented Mar 9, 2016 at 21:55
  • @juanchopanza, I wont stoop down and argue on such levels. It was not plain wrong, it was an oversimplified version of what I wanted to say. It "can be" treated as a constant pointer to first element. I will zip it and move on. seems you have lot of time on your hands to issue such demeaning statements. Commented Mar 9, 2016 at 22:00
  • @UnderDog Given that this is a question about why an array isn't a pointer, I don't think pointing out that your oversimplification is wrong is stooping down to any level. There's already too much confusion about that, and it gets tedious to see more people perpetrating it. Commented Mar 9, 2016 at 22:04

4 Answers 4

4

An array decays to a pointer to the first element of the array in most expressions. There are two cases where it does not and hence the outcome is not the same.

int array[5]; int* ptr = array; // Array decays to a pointer, OK. // Same int a = array[0]; int a = ptr[0]; // Same void foo(int*); foo(array); foo(ptr); // Not same size_t s = sizeof(array); // s is 5*sizeof(int) size_t s = sizeof(ptr); // s is sizeof(int*) // Not same int (*p1)[5] = &array; // p1 is a pointer to "an array of 5 ints" int **p1 = &ptr; // p1 is a pointer to "an int*" 
Sign up to request clarification or add additional context in comments.

Comments

4

sizeof a returns the size of the entire array in storage units (bytes). sizeof (int) returns the size of a single integer in storage units. Since a is an array of 3 integers, sizeof a / sizeof (int) gives you 3.

They always taught me that an array that it is a pointer

"They" taught you incorrectly. Unless it is the operand of the sizeof or unary & operators, an array expression will be converted ("decay") to a pointer expression, and the value of the pointer expression will be the address of the first element of the array, but an array object is not a pointer.

When you declare a, what you get in memory looks something like this:

 +---+ a:| | a[0] +---+ | | a[1] +---+ | | a[2] +---+ 

There is no object a that's separate from the array elements; there's no pointer anywhere.

Comments

3

They always taught me that an array that it is a pointer

That's your problem, right there. When you call a function and pass an array as an argument, it gets converted into a pointer to the first element. Otherwise, they're not equivalent. In particular, an array has an address, a type, and a size, whereas a pointer just has an address and a type.

This is a pretty common confusion among people learning C for the first time, and even some textbooks get it wrong.

edit: there are a few other cases where arrays "decay" to pointers, typically when they're used in an expression. See one of the other fine answers for a more-exhaustive treatment.

5 Comments

"When you call a function and pass an array as an argument, it gets converted into a pointer to the first element." If the parameter is a pointer. The key is that the parameter has to be a pointer, and pointer is just a pointer.
@juanchopanza: There's no “if”; passing an array as a function argument always causes it to decay to a pointer. If you declare int f(int a[]), it's as if you had written int f(int *a), and sizeof(a) inside the function will return the size of a pointer.
@dan04 The point is that a function can't have an array as parameter. So one doesn't even have to consider the possibility that one is dealing with an array, because the parameter is a pointer. Either that, or passing an array as argument will result in compiler error.
Of course, it's not just "When you call a function and pass an array as an argument". It's whenever an array appears in an expression, other than just to the right of & or sizeof.
@SteveSummit, that's a good point. I'll edit the answer a bit.
1

An array can decay to a pointer, but that does not mean an array is a pointer. See this SO question for details.

sizeof returns the size (in bytes) of the data type of its operand. In this case, the data type is an array of int of length three. But, since an int can be represented in different ways on different platforms, you must divide by the sizeof(int) to get the length.

See here for more details on sizeof.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.