6

Theorem says that we cannot initialize an array as a copy of another array. But we can initialize pointer as a copy of pointer that points to the first element of another array:

int a[] = {0, 1, 2}; 
int a2[] = a;       //error
int *a3 = a;        //OK

Why int a2[] = a; is an error?

vladinkoc
  • 919
  • 1
  • 8
  • 13
  • 12
    Because: **Arrays are *NOT* pointers!** – Alok Save Oct 15 '12 at 13:35
  • 3
    Long story short, use `std::array` and copy-initialize etc. all you want. – chris Oct 15 '12 at 13:35
  • @Als That in itself does not explain why there is no (simple, assignment-operator-based) syntax to copy-initialize an array. – jogojapan Oct 15 '12 at 13:43
  • 1
    @jogojapan: For my comment to not be an answer the Q should have been: *"Why are arrays non modifiable l-values?"* but the Q is *"Why we can copy pointers, but we can not copy arrays in c++"*, the answer is in my comment(because arrays are not pointers). – Alok Save Oct 15 '12 at 13:55

7 Answers7

17

Arrays can't be assigned to or initialized from another array object in C++ because they can't in C, and they can't in C for historical reasons that aren't really relevant any more.

In very early proto-C, there would have be some confusion whether an assignment like int a[] = {0}; int b[] = {0}; a = b; should copy the contents of array b to a, or re-seat the name a to refer to b. Likewise with initialization, whether a should be a copy of b or an alias. This ambiguity hasn't existed for 40 years: it soon became clear that if it were to be allowed then the sensible meaning in C (and C++) would be that it should copy, but arrays in C were never made into "proper" value types.

There's no technical reason why it's impossible, and for example you can assign a struct type that has an array as a data member. The standard simply doesn't define your code to be correct C++.

The behavior of pointers isn't directly relevant to this. Initializing a pointer (to point to the first element of an array) is a different operation from initializing an array and its contents, and the language allows different things on the RHS.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
5

Arrays are not pointers, so you can't expect to use them like pointers without running into trouble. Visit https://blogs.oracle.com/ksplice/entry/the_ksplice_pointer_challenge for an activity that will help you learn the difference.

You can initialize an array as a copy of another array if you wrap the array in a struct.

struct myarray {
  int a[3];
};

If your compiler allows GNU C++ style designated initializers:

myarray a = {a: {0, 1, 2}};

This does a copy of the struct, including a's array to a2's array.

myarray a2 = a;

The arrays will be at different places in memory:

bool is_different_array = a2.a != a.a; // true
Patater
  • 117
  • 7
0

It is possible to assign one array to another -- but only by copying the underlying data of the first array into the second (using a loop, for example). The line of code in your question:

int *a3 = a;

simply assigns the pointer called a3 to point to the address of the first element of the array a, but it does not change the underlying data that these two variables refer to (in this case integers).

Also, check this out for a clarification on the relationship between arrays and pointers.

Community
  • 1
  • 1
nickolayratchev
  • 1,136
  • 1
  • 6
  • 15
  • `a` is not a pointer. It decays to a pointer to the first element, which is what gets assigned to `a3`. Stop this "array is a pointer" madness. – avakar Oct 15 '12 at 13:40
0

An array isn't just a pointer, in your example the array a[] represents that 3 integer-sized consecutive memory addresses have been reserved in memory. If you were to try to 'copy' that array, it would also have to reserve 3 integer-sized consecutive memory addresses and copy 0 1 2 to them. The assignment operator for primitives would not be expected to do this much work.

When you create a pointer however, you are simply naming the location of a[].

Ben
  • 2,867
  • 2
  • 22
  • 32
  • "The assignment operator for primitives would not be expected to do this much work" - I don't think this is quite relevant, since arrays *aren't* primitive types (they're aggregates). That line of thought probably helps explain why nobody ever bothered to make arrays assignable in C, though. Structs are assignable despite requiring just as much copying, so arrays get left in the middle. – Steve Jessop Oct 15 '12 at 14:19
0

if you do this

int *a3 = a; 

You dont copy the Values,just the memoryadress, which is called pointer

If you wont to copy the Values of an Array, you have to define an Copy Constructor.

http://en.wikipedia.org/wiki/Copy_constructor

John Dibling
  • 99,718
  • 31
  • 186
  • 324
user1572130
  • 65
  • 10
0

Let's look at it in a different way. Arrays work on static allocation in C/C++. So we must make sure that the compiler is able to figure out the size of the array at compile time itself, which is mandatory condition with arrays because of so many goddamn reasons. So whenever the compiler encounters the '[]' notation, it expects that the memory size (that needs to be allocated at runtime) can be figured out from code itself.

When we define an array in C/C++, the memory for the array gets allocated (When I say array, I mean the cells where array elements are going to be stored). Now when you say like

int a[] = {3,4,5,6};

It is going to allocate some memory, say 16 Bytes for 4 elements, which can be figured out by the compiler at the compile time.

Now when you say

int a2[] = a;

The compiler sees the array notation '[]', but is not able to identify how much memory needs to be allocated for the array cells, which gives you an error.

When we talk about an array, it is always about the dereferenced cell pointed by a constant pointer, while when we talk about a pointer, it can exist without referencing anything, which is knows as dangling pointer. Hope it helps.

Vivek
  • 1,640
  • 1
  • 17
  • 34
  • 1
    You're idea about how compilers work is somewhat incorrect. The type of `a` in your second snippet is `int[4]`, so there is no reason why the compiler couldn't deduce the array bound for `a2`. Furthermore, you can't copy arrays even if you provide explicit bounds, so you're missing the point of the question. – avakar Oct 15 '12 at 14:00
  • @avakar Agreed. The point what I was trying to make is we cannot explicitly specify the location of an array which is what we are doing when we say int a1[] = a, it is upto the compiler to decide. Please correct me if I am wrong – Vivek Oct 15 '12 at 14:09
-1

When you want to declare an array which will be allocated on the stack, it is necessary for the compiler to know the number of elements, which is why you must declare:

int a[] = {x,y,etc..}; 

or

int a[NUMELEMENTS];

While it is acceptable to have a pointer pointing to an already existing array, you cannot create a new stack array from a pointer to an already existing array, which is what int a2[]= a; is attempting to do. The compiler doesn't know how many elements to allocate for a2.

Usually, the best way to copy an array to another array is to use std::copy.

Steve Barna
  • 1,378
  • 3
  • 13
  • 23
  • 1
    The size of the array is determined at compile-time. So the compiler fundamentally knows how large it is (which is why `sizeof a` works). – jogojapan Oct 15 '12 at 14:10