use memcpy() to copy one structure to another

S

Sourcerer

Hi all.

Can I do this to duplicate the contents of struct a in struct b

struct myStruct a, b, *aptr, *bptr;
aptr = a;
bptr = b;
Do something to initialize contents of structure a
memcpy(bptr, aptr, sizeof(myStruct));

Or is not not a good idea to assume the memory used
by my structure is contiguous ?
should I instead do it field by field.

Kev.
 
C

Chris Dollin

Sourcerer said:
Hi all.

Can I do this to duplicate the contents of struct a in struct b

struct myStruct a, b, *aptr, *bptr;
aptr = a;

Illegal. Did you mean &a?
bptr = b;

Ditto &b.
Do something to initialize contents of structure a
memcpy(bptr, aptr, sizeof(myStruct));

Or is not not a good idea to assume the memory used
by my structure is contiguous ?

It may have gaps, but sizeof will cover them all. But why not

memcpy( bptr, aptr, sizeof (*bptr) );

if you're set on using memcpy?
should I instead do it field by field.

What's wrong with

a = b;

?
 
T

Thomas Pfaff

Sourcerer said:
Hi all.

Can I do this to duplicate the contents of struct a in struct b

struct myStruct a, b, *aptr, *bptr;
aptr = a;
bptr = b;
Do something to initialize contents of structure a
memcpy(bptr, aptr, sizeof(myStruct));

memcpy (&b, &a, sizeof b); or simply b = a;
 
S

Sourcerer

Illegal. Did you mean &a?


Ditto &b.


It may have gaps, but sizeof will cover them all. But why not

memcpy( bptr, aptr, sizeof (*bptr) );

if you're set on using memcpy?


What's wrong with

a = b;

?

Wow ! that was fast.

I hadn't realized a = b would do it.

so, I could have

struct mystruct
{
char str[50];
}

struct mystruct a, b;
sprintf(a.str, "Testing 123");
b = a;

and then b.str would also contain "Testing 123" ?
 
T

Thomas Matthews

Sourcerer said:
Hi all.

Can I do this to duplicate the contents of struct a in struct b

struct myStruct a, b, *aptr, *bptr;
aptr = a;
aptr = &a;
bptr = b;
bptr = &b;
Do something to initialize contents of structure a
memcpy(bptr, aptr, sizeof(myStruct));
Try these:
b = a;
memcpy(&b, &a, sizeof(struct myStruct));

Or is not not a good idea to assume the memory used
by my structure is contiguous ?
should I instead do it field by field.
I believe that the total space occupied by a structure
is contiguous; however, the compiller is allowed to
add padding between the fields.

When copying one structure to another, memcpy can be
used. But you should have a policy when it comes
to pointer fields:
1. Copy only the pointer and have multiple pointers
to one object.
2. Create a new copy of the target object, thus having
two copies of the target object.
3. Reference counting: multiple pointers to one
object, but the number of references must be zero
before the target object is deleted.

I would copy field by field when copying to or from
a buffer (unsigned char array). Padding bytes may
be copied from one structure to another, but a buffer
may not have padding between the fields.



--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
G

Guest

Sourcerer said:
Hi all.

Can I do this to duplicate the contents of struct a in struct b

struct myStruct a, b, *aptr, *bptr;
aptr = a;
bptr = b;
Do something to initialize contents of structure a
memcpy(bptr, aptr, sizeof(myStruct));

Or is not not a good idea to assume the memory used
by my structure is contiguous ?
should I instead do it field by field.

Kev.

Juste use:
b = a;

- Dario
 
C

CBFalconer

Sourcerer said:
Can I do this to duplicate the contents of struct a in struct b

struct myStruct a, b, *aptr, *bptr;
aptr = a;
bptr = b;
Do something to initialize contents of structure a
memcpy(bptr, aptr, sizeof(myStruct));

Or is not not a good idea to assume the memory used
by my structure is contiguous ?
should I instead do it field by field.

That better be:

aptr = &a;
bptr = &b;

but you can duplicate the contents by:

b = a;

What you cannot do is check equality etc. by:

if (b == a) ...; /* not allowed */

structs are not arrays.
 
M

Martin Ambuhl

Sourcerer said:
Hi all.

Can I do this to duplicate the contents of struct a in struct b

struct myStruct a, b, *aptr, *bptr;
aptr = a;
bptr = b;
Do something to initialize contents of structure a
memcpy(bptr, aptr, sizeof(myStruct));

Why not
struct myStruct a = { /* initialize a */ }, b;
b = a;
and forget all your side issues.
 
A

Alex Fraser

Martin Ambuhl said:
Why not
struct myStruct a = { /* initialize a */ }, b;
b = a;
and forget all your side issues.

Does the assignment above invoke undefined behaviour if not all members of a
are initialised?

What about the "equivalent" memcpy()?

Alex
 
M

Martin Ambuhl

Alex said:
Does the assignment above invoke undefined behaviour if not all members of a
are initialised?

Just how, given the presence of an initializer, do you propose to
partially initialized the structure?
What about the "equivalent" memcpy()?

Who cares about function calls when a simple assignment will do?
 
D

Default User

Alex said:
Does the assignment above invoke undefined behaviour if not all members of a
are initialised?


If an array is partially intialized, the rest of the elements are
default initialized. So no undefined behavior, as all elements will have
values.



Brian Rodenborn
 
C

CBFalconer

Martin said:
Just how, given the presence of an initializer, do you propose
to partially initialized the structure?

structures do not have to be initialized at declaration time.
Since a structure with an uninitialized component is an
uninitialized structure, copying it via structure assignment
should be undefined behaviour. Yet I expect it will go unpunished
on most machines other than the DS9000.
 
A

Alex Fraser

CBFalconer said:
structures do not have to be initialized at declaration time.
Since a structure with an uninitialized component is an
uninitialized structure, copying it via structure assignment
should be undefined behaviour. Yet I expect it will go unpunished
on most machines other than the DS9000.

Thank you, that makes sense. I was thinking in practical terms when I
phrased the question: assigning a structure where the source is partially
initialised is much more likely to happen than where it is completely
uninitialised, but the effect is identical in either case.

I suppose, in fact, it is no different to:

int a, b; /* uninitialised */
b = a; /* undefined behaviour (since a may be a trap representation?) */

But I wonder if the same still applies with the notionally equivalent
memcpy(). I think that question boils down to:

unsigned char a, b; /* uninitialised */
b = a; /* undefined behaviour? */

Alex
 
K

kal

Alex Fraser said:
int a, b; /* uninitialised */
b = a; /* undefined behaviour (since a may be a trap representation?) */

I suppose anything is possible. It may be that the type "int"
is 33 bits in size and at declaration time bit 32 is set to 1.
It is reset to zero only when a value is explicitly assigned to
the variable. Any attempt to read the contents of the variable
when bit 32 is not zero terminates the program execution.

But for us bozos who make do with 16 or 32 bit integers, all bit
patterns represent valid integer values. Hence, unitialized does
not means "undefined" or "trap representation", it just means that
the value in it is not the one we want to start with.

Can someone expound on "trap representation" vis-a-vis integers?
 
R

Richard Bos

I suppose anything is possible. It may be that the type "int"
is 33 bits in size and at declaration time bit 32 is set to 1.
It is reset to zero only when a value is explicitly assigned to
the variable. Any attempt to read the contents of the variable
when bit 32 is not zero terminates the program execution.

That's one possibility, yes.
But for us bozos who make do with 16 or 32 bit integers, all bit
patterns represent valid integer values.

Nope. Usually, but not necessarily. That is, yes, INT_MAX must be so
large that a 16-bit int needs to use all bits as value or sign bits, but
a 32-bit int is allowed to have (e.g.) 30 value bits, one sign bit, and
one trap bit.
Hence, unitialized does not means "undefined" or "trap representation",
it just means that the value in it is not the one we want to start with.

No. It means "the value is undefined and may be illegal". It does not
mean "the value _must_ be illegal"; it does not mean "the value _cannot_
be illegal"; it means "you do not know whether the value is legal or
not".

Richard
 
D

Dan Pop

In said:
I suppose anything is possible. It may be that the type "int"
is 33 bits in size and at declaration time bit 32 is set to 1.
It is reset to zero only when a value is explicitly assigned to
the variable. Any attempt to read the contents of the variable
when bit 32 is not zero terminates the program execution.

This is an excellent example of trap representation vis-a-vis integers.
But for us bozos who make do with 16 or 32 bit integers, all bit
patterns represent valid integer values.

This is not necessarily true. Even if all the bits are actually used
by the representation, the standard allows -0 for one's complement and
sign-magnitude to be a trap representation, as well as the representation
with the sign bit set and all the value bits reset for two's complement
(normally, this is corresponding to type_MIN).
Hence, unitialized does
not means "undefined" or "trap representation", it just means that
the value in it is not the one we want to start with.

According to the standard, it is an unspecified value, and this includes
trap representations.
Can someone expound on "trap representation" vis-a-vis integers?

All the trap representations not involving padding bits (bits that do not
contribute to the value) have already been described above. Once you
have padding bits, they can have the effect you have already explained.

Dan
 

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

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top