|
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?
|
|
|
| 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.
| |
|
| > 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
|
|
|
|
|