Copying one array to another array

J

janus

Hello All,

I was not able to carry out the below,

int array1 = {{2,1},{1,0}};
int array2 = {{3, 5},{7,9}};

array2 = array1;

I got incompatible type error.

My only saving grace was memcpy... Now, I would want somebody to
explain why array to array copying failed.

Regards,
Janus
 
B

Ben Bacarisse

janus said:
I was not able to carry out the below,

int array1 = {{2,1},{1,0}};
int array2 = {{3, 5},{7,9}};

array2 = array1;

It is better to cut and paste (or similar). Neither array1 nor array2
is declared as an array so your example does illustrate what you were
doing.
I got incompatible type error.

My only saving grace was memcpy... Now, I would want somebody to
explain why array to array copying failed.

There are lots of levels for such an explanation. The simplest is
that C is designed that way: arrays are not "assignable". Another is
slightly more technical: the name of an array is converted to a
pointer to its first element[1] so that both sides of what appears to
be an array assignment are, in fact, pointer valued expressions.
Worse, the one on the left is not a modifiable lvalue -- it is just a
value and you can't assign to such a thing. One could get more
technical still and explain it all in terms used by the language
standard, but I doubt that would help.

There are also other kinds of explanation that would explain why is C
designed this way, but I am not sure I fancy trying that one!

So, in short, C is just like that. You can't assign whole arrays and
you have to use something like memcpy instead.

[1] There are a few exceptions, but lets keep this simple.
 
C

Chris M. Thomasson

janus said:
Hello All,

I was not able to carry out the below,

int array1 = {{2,1},{1,0}};
int array2 = {{3, 5},{7,9}};

array2 = array1;

I got incompatible type error.

My only saving grace was memcpy... Now, I would want somebody to
explain why array to array copying failed.

FWIW, you can embed an array in a struct:
__________________________________________________
struct array
{
int buffer[4];
};


int
main(void)
{
struct array a1;
struct array a2 = { { 1, 2, 3, 4 } };

a1 = a2;

return 0;
}
__________________________________________________
 
S

santosh

janus said:
Hello All,

I was not able to carry out the below,

int array1 = {{2,1},{1,0}};
int array2 = {{3, 5},{7,9}};

You probably meant:

int array1[][2] = {{2, 1}, {1, 0}};

and so on.
array2 = array1;

C doesn't natively support assigning one array to another. You'll have
to use a loop. For example:

for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
printf("%d\n", array1[j]);
}
}

My only saving grace was memcpy...

How was memcpy() your saving grace??
 
S

santosh

santosh said:
janus said:
Hello All,

I was not able to carry out the below,

int array1 = {{2,1},{1,0}};
int array2 = {{3, 5},{7,9}};

You probably meant:

int array1[][2] = {{2, 1}, {1, 0}};

and so on.
array2 = array1;

C doesn't natively support assigning one array to another. You'll have
to use a loop. For example:

for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
printf("%d\n", array1[j]);
}
}


The above loop just prints the values of array1. To copy it into
array2, something like the code below is needed.

for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
array2[j] = array1[j];
}
}

This assumes that both arrays MAX elements for both dimensions, and
you want a simple element by element copy of the whole array. For
fancier scenarios, you'll have to adjust the parameters of the loop.
 
R

Richard Tobin

Ben Bacarisse said:
There are lots of levels for such an explanation. The simplest is
that C is designed that way: arrays are not "assignable". Another is
slightly more technical: the name of an array is converted to a
pointer to its first element[1] so that both sides of what appears to
be an array assignment are, in fact, pointer valued expressions.
Worse, the one on the left is not a modifiable lvalue -- it is just a
value and you can't assign to such a thing.

You can see this last point by trying

*(int (*)[2][2])array2 = *(int (*)[2][2])array1;

which is still an error, even though you have succeeded in getting
hold of the array (as an lvalue) rather than a pointer to its first
element.

-- Richard
 
B

Ben Bacarisse

santosh said:
janus said:
Hello All,

I was not able to carry out the below,

int array1 = {{2,1},{1,0}};
int array2 = {{3, 5},{7,9}};

You probably meant:

int array1[][2] = {{2, 1}, {1, 0}};

and so on.
array2 = array1;

C doesn't natively support assigning one array to another. You'll have
to use a loop. For example:

for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
printf("%d\n", array1[j]);
}
}


[I note you correct this to a copy in another post]. This is, for
me, a messy way to do it. If either dimension changes (or, worse,
the number of dimensions) this code must be found and changed.
How was memcpy() your saving grace??

Maybe because memcpy(array2, array1, sizeof array2); does what is
wanted in a way that need not change if the array sizes do? Of course
it breaks on some changes (such as moving the code into a function)
but it does enough to be described as a solution even if you'd not go
so far as to call it a saving grace.
 
S

santosh

Ben said:
santosh said:
janus wrote:
I was not able to carry out the below,

int array1 = {{2,1},{1,0}};
int array2 = {{3, 5},{7,9}};
array2 = array1;

C doesn't natively support assigning one array to another. You'll have
to use a loop. For example:

for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) {
printf("%d\n", array1[j]);
}
}


[I note you correct this to a copy in another post]. This is, for
me, a messy way to do it. If either dimension changes (or, worse,
the number of dimensions) this code must be found and changed.
How was memcpy() your saving grace??

Maybe because memcpy(array2, array1, sizeof array2); does what is
wanted in a way that need not change if the array sizes do? Of course
it breaks on some changes (such as moving the code into a function)
but it does enough to be described as a solution even if you'd not go
so far as to call it a saving grace.


Yes, thanks for mentioning that. But memcpy() will also have to be
checked and modified, if necessary, when either array's size or
dimensions change.
 
B

Ben Bacarisse

Ben Bacarisse said:
There are lots of levels for such an explanation. The simplest is
that C is designed that way: arrays are not "assignable". Another is
slightly more technical: the name of an array is converted to a
pointer to its first element[1] so that both sides of what appears to
be an array assignment are, in fact, pointer valued expressions.
Worse, the one on the left is not a modifiable lvalue -- it is just a
value and you can't assign to such a thing.

You can see this last point by trying

*(int (*)[2][2])array2 = *(int (*)[2][2])array1;

which is still an error, even though you have succeeded in getting
hold of the array (as an lvalue) rather than a pointer to its first
element.

Hmm... Unless I've missed your point, I don't agree. 6.3.2.1 p3
(which governs what either side of array2 = array1; means) also
applies to your expressions.

*(int (*)[2][2])array2 is

"an expression that has type 'array of type'"

so it

"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"

in exactly the same way. At no point do you get hold of the array as
an lvalue. One could argue that there is an array lvalue there,
fleetingly, which immediately gets converted, but the standard does
not word it that way and, in any case, the same would be true of both
forms of the assignment.
 
B

Ben Bacarisse

santosh said:
Ben said:
santosh <[email protected]> writes:
C doesn't natively support assigning one array to another. You'll have
to use a loop. For example:

for (int i = 0; i < MAX; i++) {
for (int j = 0; j < MAX; j++) { [corrected:]
array2[j] = array1[j];
}
}
How was memcpy() your saving grace??

Maybe because memcpy(array2, array1, sizeof array2); does what is
wanted in a way that need not change if the array sizes do?

Yes, thanks for mentioning that. But memcpy() will also have to be
checked and modified, if necessary, when either array's size or
dimensions change.

I don't follow. Your "if necessary" means that your statement is
almost a tautology, but my point is that it is not necessary.
 
R

Richard Tobin

Ben Bacarisse said:
Hmm... Unless I've missed your point, I don't agree. 6.3.2.1 p3
(which governs what either side of array2 = array1; means) also
applies to your expressions.

Oops, yes, you're right. I was misremembering.

-- Richard
 
R

Richard Bos

janus said:
I was not able to carry out the below,

int array1 = {{2,1},{1,0}};
int array2 = {{3, 5},{7,9}};

array2 = array1;

I got incompatible type error.

Yes, so do I. That is a weird way to phrase that error.

Note that if the above is literally what you had in your code, you also
should have had warnings on the declaration of the "arrays". What you
have above are definitions of two _ints_, not two arrays of int. For
obvious reasons you cannot initialise an int to an array of int,
although AFAICT the excess initialisers are ignored. However, a good
compiler set to a decent warning level will warn.
If I correct that, however, I, too, get an error saying "incompatible
types in assignment" on the assignment. And that's an unclear way of
stating what the real problem is: you can't assign to an array.
My only saving grace was memcpy... Now, I would want somebody to
explain why array to array copying failed.

Because you cannot assign to an array. There's nothing really
incompatible about it - you simply cannot assign anything to a whole
array at once. You'll have to use

Richard
 
J

janus

I was not able to carry out the below,


int array1[2][2] = {{2,1},{1,0}};
int array2[2][2] = {{3, 5},{7,9}};


array2 = array1;



Hell on earth :) , I am sorry for that omission. Please bear with me.
 
B

bartc

janus said:
Hello All,

I was not able to carry out the below,

int array1 = {{2,1},{1,0}};
int array2 = {{3, 5},{7,9}};

array2 = array1;

I got incompatible type error.

My only saving grace was memcpy... Now, I would want somebody to
explain why array to array copying failed.

C can't do assignments of arbitrary length, except for structs. If a
compatible struct is defined (and it just needs to have the same number of
bytes as the array), then the following is possible:

#include "stdio.h"
#include "stdlib.h"

typedef struct{int array[2][2];} intarray22;

int main(void) {
int array1[2][2] = {{10,20},{30,40}};
int array2[2][2] = {{0,0},{0,0}};

*(intarray22*)array2 = *(intarray22*)array1;

printf ("Array2 =
{{%d,%d},{%d,%d}}\n",array2[0][0],array2[0][1],array2[1][0],array2[1][1]);

}
 
E

Eric Sosman

C can't do assignments of arbitrary length, except for structs.

Nitpick: "and unions."
C can't do assignments of arbitrary length, except for structs. If a
compatible struct is defined (and it just needs to have the same number
of bytes as the array), then the following is possible:

#include "stdio.h"
#include "stdlib.h"

typedef struct{int array[2][2];} intarray22;

int main(void) {
int array1[2][2] = {{10,20},{30,40}};
int array2[2][2] = {{0,0},{0,0}};

*(intarray22*)array2 = *(intarray22*)array1;

Non-nitpick: I don't think this is guaranteed to work.
It is possible that sizeof(intarray22) > 2*2*sizeof(int) --
that is, your parenthetical remark might not hold. There
could be alignment problems, too.
 
P

Peter Nilsson

I was not able to carry out the below,

int array1[2][2] = {{2,1},{1,0}};
int array2[2][2] = {{3, 5},{7,9}};

array2 = array1;

Standard C doesn't allow array assignments.

What have you got against...

memcpy(array2, array1, sizeof array2);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top