5

These of 2 of the probably many ways of declaring arrays (and allocating memory for them) in c++

1. int a[3];

2. int *b = new int[3];

I want to understand how c++ is treating the two differently.

a. In both cases, i can access array with the following syntax: a[1] and b[1]

b. When i try cout<< a and cout<< b, both print the addresses of first element of respective arrays.

It looks to me as if both a and b are being treated as pointers to first elements of arrays.

c. But strangely, when i try to do cout << sizeof(a) and sizeof(b) they print different values - 4 and 12 respectively.

I don't understand why in case of sizeof(b), the size of entire array is being printed.

3
  • 4
    static allocation vs dynamic allocation, one is allocated on the stack, the other on the heap Commented Jul 5, 2011 at 22:02
  • 5
    @Kshitij: That's automatic allocation, not static. Static is load-time allocation (for global objects). Commented Jul 5, 2011 at 22:06
  • @Kerrek SB - can you elaborate the meanings and difference between automatic allocation and static allocation? I tried googling but dint found anything good. Commented Jul 6, 2011 at 19:19

4 Answers 4

8

a is an array (type int [3])
b is a pointer (type int*)

In C++ they are completely different things.

The sizeof an array is the number of elements times the size of each element.
The sizeof a pointer is independent of the size of the array (usually 4 or 8 bytes).

The only thing that arrays and pointers have in common is that arrays often "decay" to pointers in several situations. That's what's happening when you print out their value.

Sign up to request clarification or add additional context in comments.

10 Comments

Along with the convention that p[n] is treated as *(p + n), so you can treat pointers like arrays, too.
-1: b is not a pointer to an array. b is a pointer to int. int (*b)[N] is a pointer to an array
@Armen: It's both. Its type is int*, but it clearly points to an array as you must use delete[] with it. I'll clarify that.
@Peter Alexander: I removed my downvote and I know that you mean good, but terminologically, "pointer to array" is still incorrect, IMHO
@Dev Kanchen: Yes, it's a typo in the OP.
|
3

As you noted, it seems as though both a and b are pointers to the start of the array. But in reality, only b is a pointer. a is actually an array.

The difference between the two is subtle when writing (or reading) code. The variable a is treated as a regular variable (just like an int or double) in that it has an automatically allocated portion of memory assigned to it. For comparison, suppose you had declared int i. The variable i is the name given to a certain set of contiguous bytes in memory to hold an integer value (4 bytes on your machine). Similarly, a is the name given to the set of contiguous bytes which holds your array (12 bytes in your case).

In contrast b is only a pointer to a single memory location. In your case, there is a block of 12 bytes which is dynamically allocated (via new int[3]). b itself is an automatically allocated 4-byte pointer which points to the first int value in that 12 byte block.

So they really are two different kinds of things. This is made less clear to C++ programmers. One reason for this is the fact that you can use the [] operator on both types. Another reason is that arrays implicitly degenerate to pointers in several situations (e.g. in the function void Foo(int a[3]);, a is not actually an array, but a pointer to the beginning of the array). But don't be fooled - arrays are not pointers (as many people claim), and pointers are definitely not arrays.

Comments

0

1 is allocated on the stack. Arrays on the stack must have a size known at compile-time.

2 is allocated on the heap. Arrays on the heap have no such requirement. Remember if you allocate with new[] you need to deallocate it later with delete[]:

int* b = new int[3];
delete[] b;

4 Comments

1 isn't necessarily on the stack. If it's a member of a class and an instance of that class is allocated on the heap then the array will be in the heap. Do not confuse "the stack" with automatic storage.
1) is sort of true, but things like alloca or variable-length arrays effectively allow you to allocate automatic objects of variable length, too.
Good point, although I just assumed that in his example it was on the stack.
Also the first example could be global, hence neither on the stack nor on the heap, but static.
0

C++ arrays in the stack have a limitation that

int array[10];
sizeof(array) needs to be compile-time constant and
sizeof(array[0])==sizeof(array[1])==...==sizeof(array[9])

C++ arrays in the heap only have the 2nd limitation, but not the first one. (this allows array size to be determined on runtime)

1 Comment

Just to clarify: the size of a dynamically-allocated array must be determined before the actual allocation, and will probably also be stored in a variable. There is no way to look at the array itself and deduce its size.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.