Unix Programming - copy structs unto structs?

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > November 2006 > copy structs unto structs?





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author copy structs unto structs?
atv

2006-11-17, 7:30 am

Is it possible to copy a struct ptr unto a struct ptr like for example:
*structptr=*structptr;

so i would have an exact copy of all the values?

i ask this because when getting a ptr to shared memory access i wonder
how to do this.
i can't do shmdataptr=struct_ptr because that would destroy/replace my
shm pointer.

It's not necessary to write out all the values in a struct and put that
in there is it ?

Pascal Bourguignon

2006-11-17, 7:30 am

atv <alef@xs4all.nl> writes:

> Is it possible to copy a struct ptr unto a struct ptr like for example:
> *structptr=*structptr;
>
> so i would have an exact copy of all the values?
>
> i ask this because when getting a ptr to shared memory access i wonder
> how to do this.
> i can't do shmdataptr=struct_ptr because that would destroy/replace my
> shm pointer.
>
> It's not necessary to write out all the values in a struct and put
> that in there is it ?


AFAIK, in C, you cannot copy a structure like this.


You could try to copy the the memory block, but I'm not sure it's
entirely portable.

struct data* src;
struct data* dst;

memcpy(dst,src,sizeof(*src));


AFAIK, the only portable way in C to copy a structure, is to copy each field:

void copy_data(struct data* dst,struct data* src){
dst->char_field=src->char_field;
dst->short_field=src->short_field;
dst->int_field=src->int_field;
dst->float_field=src->fload_field;
copy_other_struct(&(dst->other_struct),&(src->other_struct));
switch(src->union_selector){
case 0: dst->union_field.char_field=src->union_field.char_field; break;
case 1: dst->union_field.short_field=src->union_field.short_field; break;
case 2: dst->union_field.int_field=src->union_field.int_field; break;
case 3: copy_yet_another_struct(&(dst->union_field.another_struct),
&(dst->union_field.another_struct)); break;
/* ... */
}
dst->shared_pointer=src->shared_pointer;
dst->deep_pointer=new_deep(src->deep_pointer);
/* for example: */
dst->some_immutable_string=src->some_immutable_string;
dst->mutable_string=newstr(src->mutable_string);
/* ... */
}


--
__Pascal Bourguignon__ http://www.informatimago.com/
Litter box not here.
You must have moved it again.
I'll poop in the sink.
Rainer Temme

2006-11-17, 7:30 am

atv wrote:

> Is it possible to copy a struct ptr unto a struct ptr like for example:
> *structptr=*structptr;


Albeit unrelated to unix ... yes this is a valid statement in
C language, and it does copy from the memorylocation the right-pointer
points-to to the memorylocation the left-pointer points-to

> so i would have an exact copy of all the values?


Yes ... but remember, if some struct members are pointers, only
the pointer is copied, not the location these pointers are pointing
to.

> i ask this because when getting a ptr to shared memory access i wonder
> how to do this.
> i can't do shmdataptr=struct_ptr because that would destroy/replace my
> shm pointer.


yes, as said, you can do a

*shmdataptr = *struct_ptr ;

or a

*shmdataptr = struct ;

or a

memcpy(shmdataptr,struct_ptr,sizeof(*shm
dataptr));

> It's not necessary to write out all the values in a struct and put that
> in there is it ?


No, but again, pointers (as members of the struct) will still point to
the same memorylocation.

Rainer

Rainer Temme

2006-11-17, 7:30 am

Pascal Bourguignon schrieb:
> AFAIK, in C, you cannot copy a structure like this.


#include <stdio.h>
#include <stdlib.h>

$cat y.c
typedef struct str_x
{
int a;
char *b;
int c;
} X;

void printX(X *x)
{
printf("X(%p): a=%d b=[%p/%s] c=%d\n",
x,x->a,
x->b, x->b ? x->b : "",
x->c);
}

int main(int c,char **v)
{
X *p1,*p2;

p1=malloc(sizeof(X));
p2=malloc(sizeof(X));

p1->a=1; p1->b="a"; p1->c=2;

printX(p1);
*p2=*p1;
printX(p2);
return(0);
}

$ y
X(0x804a008): a=1 b=[0x8048605/a] c=2
X(0x804a018): a=1 b=[0x8048605/a] c=2

Rainer
Maxim Yegorushkin

2006-11-17, 7:30 am


atv wrote:

> Is it possible to copy a struct ptr unto a struct ptr like for example:
> *structptr=*structptr;
> so i would have an exact copy of all the values?


It is.

struct S
{
int i;
double d;
};

int main()
{
struct S a = {0,0}, b = {0,0}, *pa = &a, *pb = &b;

a = b;
*pa = *pb; // the effect is the same as a = b

return 0;
}


> i ask this because when getting a ptr to shared memory access i wonder
> how to do this.
> i can't do shmdataptr=struct_ptr because that would destroy/replace my
> shm pointer.


To reassign a value pointed to by ptr, you do *ptr = x;. To reassign
the pointer itself you do ptr = y;.

> It's not necessary to write out all the values in a struct and put that
> in there is it ?


In C, struct's are as assignable as int's are. Just copy structs as you
would copy an int.

atv

2006-11-17, 7:30 am

> Ok, thanks everyone!
gr,
Alef

Casper H.S. Dik

2006-11-17, 7:30 am

"Maxim Yegorushkin" <maxim.yegorushkin@gmail.com> writes:

>In C, struct's are as assignable as int's are. Just copy structs as you
>would copy an int.


Indeed; only in the very early incantations of C (K&R, first edition),
struct copying was not well-defined (it worked on some but not all compilers)

Casper

SM Ryan

2006-11-17, 1:22 pm

# *shmdataptr = *struct_ptr ;
#
# or a
#
# *shmdataptr = struct ;

# memcpy(shmdataptr,struct_ptr,sizeof(*shm
dataptr));

Assigning structs or unions is not exactly the same as memcpy.
The compiler is allowed to put filler bytes into a struct for
alignment. memcpy, memcmp, etc effect all bytes in the struct
whether filler or field. Struct assignments might skip filler
bytes. This can byte you in the behind if you're playing type
bending games with union.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
So basically, you just trace.
Rainer Temme

2006-11-17, 1:22 pm

SM Ryan wrote:
> # *shmdataptr = *struct_ptr ;
> #
> # or a
> #
> # *shmdataptr = struct ;
>
> # memcpy(shmdataptr,struct_ptr,sizeof(*shm
dataptr));
>
> Assigning structs or unions is not exactly the same as memcpy.
> The compiler is allowed to put filler bytes into a struct for
> alignment. memcpy, memcmp, etc effect all bytes in the struct
> whether filler or field. Struct assignments might skip filler
> bytes. This can byte you in the behind if you're playing type
> bending games with union.


Can you supply an example for this?

Rainer
shakahshakah@gmail.com

2006-11-17, 7:23 pm

On Nov 17, 2:10 pm, Rainer Temme <Rainer.Te...@NoSpam.Siemens.Com>
wrote:
> SM Ryan wrote:
>
>
>
> Rainer


I encountered this recently, something along the lines of:

struct A {
int n ;
char[1] ch ;
} ;

struct B {
int n ;
char[1] ch ;
char[2] ch2 ;
} ;

func(B *b, A *a) {
memset(b, 0, sizeof(B)) ;
*((A *) b) = *a ;
// b->ch2 probably has garbage in it from A's padding
}

Rainer Temme

2006-11-17, 7:23 pm

shakahshakah@gmail.com wrote:
> I encountered this recently, something along the lines of:
>
> struct A {
> int n ;
> char[1] ch ;
> } ;
>
> struct B {
> int n ;
> char[1] ch ;
> char[2] ch2 ;
> } ;
>
> func(B *b, A *a) {
> memset(b, 0, sizeof(B)) ;
> *((A *) b) = *a ;
> // b->ch2 probably has garbage in it from A's padding
> }


Well, but what you do invokes undefined behaviour ...
you cast b to be typeof A* which it isn't ... and complain
if something goes wrong!?

If you want to do what you do, your struct B needs to be defined like this:

struct B {
struct A a;
char ch2[2];
}

That way you can assign
b.a = *a;
or memcpy(&(b.a,a,sizeof(*a))) without undefined behaviour.

Rainer
David Schwartz

2006-11-17, 7:23 pm


Rainer Temme wrote:

> Well, but what you do invokes undefined behaviour ...
> you cast b to be typeof A* which it isn't ... and complain
> if something goes wrong!?


True, but you can cause the same problem with something that seems a
lot more reasonable. Consider:

struct foo *a, *b;

*a=*b;
if(memcmp(a, b, sizeof(struct foo))!=0)
{
/* can we ever get here? */
}

DS

shakahshakah@gmail.com

2006-11-17, 7:23 pm

On Nov 17, 5:59 pm, Rainer Temme <Rainer.Te...@NoSpam.Siemens.Com>
wrote:
> shakahsha...@gmail.com wrote:
>
>
>
> you cast b to be typeof A* which it isn't ... and complain
> if something goes wrong!?
>
> If you want to do what you do, your struct B needs to be defined like this:
>
> struct B {
> struct A a;
> char ch2[2];
> }
>
> That way you can assign
> b.a = *a;
> or memcpy(&(b.a,a,sizeof(*a))) without undefined behaviour.
>
> Rainer


I'm not complaining by any means, just supplying an example as you
requested.

Rainer Temme

2006-11-18, 1:29 am

NNTP-Posting-Host: pd9e08431.dip0.t-ipconnect.de
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
X-Trace: online.de 1163832045 14183 217.224.132.49 (18 Nov 2006 06:40:45 GMT)
X-Complaints-To: abuse@einsundeins.com
NNTP-Posting-Date: Sat, 18 Nov 2006 06:40:45 +0000 (UTC)
User-Agent: Thunderbird 1.5.0.8 (Windows/20061025)
In-Reply-To: <1163806046.373883.58400@m73g2000cwd.googlegroups.com>
Xref: number1.nntp.dca.giganews.com comp.unix.programmer:173128

David Schwartz wrote:
> True, but you can cause the same problem with something that seems a
> lot more reasonable. Consider:
>
> struct foo *a, *b;
>
> *a=*b;
> if(memcmp(a, b, sizeof(struct foo))!=0)
> {
> /* can we ever get here? */
> }


Well, this addresses the question if padding is copied with
*a = *b or if its not copied.

But for any use of just members of the structures (even if they
mob together in unions) this is meaningless, because always the
largest member of a union will be copied.

For 'most' implementations of *a = *b i would assume that the
result of the memcmp() would be zero, because on modern
architectures it's much faster to copy a few bytes more rather
than copying fewer bytes but invoce multiple copies.

Rainer
Rainer Temme

2006-11-18, 1:29 am

NNTP-Posting-Host: pd9e08431.dip0.t-ipconnect.de
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
X-Trace: online.de 1163832125 14183 217.224.132.49 (18 Nov 2006 06:42:05 GMT)
X-Complaints-To: abuse@einsundeins.com
NNTP-Posting-Date: Sat, 18 Nov 2006 06:42:05 +0000 (UTC)
User-Agent: Thunderbird 1.5.0.8 (Windows/20061025)
In-Reply-To: <1163807231.196021.104540@h48g2000cwc.googlegroups.com>
Xref: number1.nntp.dca.giganews.com comp.unix.programmer:173129

shakahshakah@gmail.com wrote:
> I'm not complaining by any means, just supplying an example as you
> requested.


No, sorry. I was requesting an example where copying of
structures of the 'same' type causes problems. (Like the
example David Schwartz supplied.

Rainer


Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com