Re: performing a "deep copy" on a nested structure



Alfonso Morra wrote:
Hi,

I have the ff data types :

Sorry, but I work on the ff library and I don't recognise them ;-)

Seriously, how is anyone meant to know what you mean by ff in the above statement.

typedef struct {
Header *hdr ;
char *subject ;
Key key ;
ValueTypeEnum type ;
Value value ;
size_t size ;
}MotherStruct ;

<snip>

Pseudo code:
=============

It is better to post actual compilable code, or as close as you can get to compilable as possible than pseudo code. Obviously when your problem is "why doesn't this compile" we don't expect it to compile.


MotherStruct *pMS_source = (MotherStruct*)calloc(1, sizeof(MotherStruct));

You don't need to cast the result of malloc/calloc and if the compiler complains when you don't you have done something wrong. Also, you can use the size of what you are pointing at and simplify it to
MotherStruct *pMS_source = calloc(1, sizeof *pMS_source);
However, calloc sets all bits zero which is not necessarily how a null pointer is represented


pMS_source->hdr = CreateHeader();
pMS_source->subject = strdup("Test Subject") ;
pMS_source->key = CreateKey("Test", 2000) ;
pMS_source->type = VAL_STRING ;
pMS_source->value.sval = strdup("Homer Simpson") ;

You have just overwritten all the fields, so why did you bother with calloc? Why not use malloc and save having the space initialised to all bits zeros.


Also, strdup is not a standard C function and it is *not* available on all systems.

pMS_source->size = /* How do I calculate this ? */

That depends on what it is meant to contain.

void MakeMSClone(MotherStruct *pMS_Dest, const MotherStruct *pMS_source) {
     memmove(pMS_dest,pMS_source, pMS_Source->size) ;

Assuming that pMS_dest and pMS_source cannot overlap, which I am guessing is a requirement, you could use memcpy instead of memmove. I tend to reserve memmove for when it is legal for the source and destinations to overlap.


Based on this you wanted
pMS_source->size = sizeof *pMS_source;
However, if that was what you want to use the size of you don't need it at all since you could do:
memmove(pMS_dest,pMS_source, sizeof *pMS_source);


I think your problem is probably that you have not yet understood that memmove and memcpy do NOT perform a deep copy. I.e. after the copy pMS_dest->subject and pMS_source->subject will point to the SAME location. So if you then did
pMS_source->subject[0]='A';
you would affect both of them.


}

MTIA
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
.



Relevant Pages

  • [PATCH 37/39] move __get_user and __put_user into uaccess.h
    ... * Context: User context only. ... * data types like structures or arrays. ... * Returns zero on success, ...
    (Linux-Kernel)
  • [PATCH 26/39] merge getuser
    ... * Context: User context only. ... * This macro copies a single simple variable from user space to kernel ... * data types like structures or arrays. ... * Returns zero on success, ...
    (Linux-Kernel)
  • Re: Changing criteria in queries
    ... This prevents dividing by zero and may eliminate the overflow. ... >> All this begs the serious issue of why you are changing data types. ... >> Tom Ellison ...
    (microsoft.public.access.queries)
  • Re: Trap for #Error
    ... if you refer to a text box in a subreport and the subreport has no ... If the data types do not match, ... You can convert nulls to zero with Nz, but I don't believe that will solve ... "Alan Fisher" wrote in message ...
    (microsoft.public.access.reports)