[ACCEPTED]-C Programming. How to deep copy a struct?-deep-copy

Accepted answer
Score: 21

Simply:

childB.usage = childA.usage;

0

Score: 10

Shouldn't it be:

memcpy(&(childB.usage), &(childA.usage), sizeof(rusage))

0

Score: 3

EDIT: Ok, I misread the question, you only wanted to copy the usage field; so my answer is a bit unrelated. I don't delete it because it can still remind beginners of the potential aliasing problem when assigning or duplicating a structure containing pointers.

The memcpy or assignement of the other answers 12 will work, of course. The only danger in 11 your structures comes from the pointer to 10 name. If you copy one struct to the other 9 you will have both structure containing 8 the same pointer and pointing to the same memory. You 7 created an alias. this means if yoy change 6 the name in the allocated space, it will 5 be visible from the other struct. Furthermore, there 4 is the danger of a double free if you pass your 3 structure to standard free function. To 2 make a real duplicate of the struct you 1 should do something like that:

memcpy(&childA,&childB, sizeof(rusage));    
if(childB.name)
  childA.name = strdup(childB.name);

or alternatively

childA = childB;
if(childB.name)
  childA.name = strdup(childB.name);
Score: 0

first, the correct code is

memcpy(&childA,&childB, sizeof(child));

second, this will 4 copy the values asis, so for all those long 3 and time structs it will be safe, but the 2 char* name parameter you have will pointer 1 to the same original value.

Score: 0

childB.usage = childA.usage

Since you have 7 the entire structure inside the child structure, simple 6 copy suffices. If you had a pointer to rusage 5 structure inside child structure, it could 4 have been a problem. In that case, you would 3 have had to allocate memory for childB.usage 2 and then do a memcpy so that if anyone modifies/deletes 1 childA, childB will be unharmed.

Score: 0

You could two that in two ways, as others 7 have mentioned.

1) childB.usage = childA.usage;
2) memcpy(&childB.usage, &childA.usage, sizeof(rusage));

First 6 argument of memcpy is the destination, second 5 one is the source and the third one is length 4 (how many bytes you want to copy). From 3 the code you have posted, you were trying 2 to copy the whole childB to childA, which 1 is really not you wanted.

Score: 0

in this file I copy the members of origine 3 to destinazione, first only using assignments 2 and strcpy, then, i copy origine to memres, using 1 only memcpy

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

typedef struct inner
{
    char *parola;
    int n;
} interna;

typedef struct outer
{
    struct inner *ptr;
    int numeroesterno;
} esterna;


struct another
{
    struct inner *ptr;
    int numero;
};    //never forget ; here

int main(void)
{
    esterna *origine; //ptr to structs
    struct another *destinazione;
    struct another *memres;

    char *tmpParola;
    tmpParola = malloc(30*sizeof(char));
    strcpy(tmpParola, "AAAAA");

    interna *tmp;  //remember the TYPEDEF, and don't use struct interna
    tmp = (interna *)malloc(sizeof(struct inner));
    // if you use struct interna in sizeof you get
    //  error: invalid application of ‘sizeof’ to incomplete type ‘struct interna’ 

    tmp->n = 500;
    tmp->parola = tmpParola;

    origine = (esterna *)malloc(sizeof(struct outer));

    origine->numeroesterno = 2;
    origine->ptr = tmp;  //the data structer pointed by tmp has already been allocated and set

    // now I have the structure allocated and set, I want to copy this on destinazione
    destinazione = (struct another *)malloc(sizeof(struct another));

    destinazione->numero = origine->numeroesterno;

    //destinazione->ptr = tmp;  //in this case you don't copy struct inner, it's just a reference

    destinazione->ptr = (interna *)malloc(sizeof(struct inner));
    destinazione->ptr->parola = malloc(sizeof(char)*30);
    strcpy(destinazione->ptr->parola, origine->ptr->parola);
    destinazione->ptr->n = 111;

    //modify origine

    origine->numeroesterno = 9999;
    strcpy(origine->ptr->parola, "parola modificata in origine");

    //print destinazione

    printf("\nparola in destinazione :%s\n", destinazione->ptr->parola);
    printf("\nparola in origine :%s\n", origine->ptr->parola);

    //you can see that destinazione is a copy, because mofifying origine, destinazione deosn't change

    //now we play with memcpy

    memres = (struct another *)malloc(sizeof(struct another));

    memcpy(memres, destinazione, sizeof(destinazione)); //till here, is AAAAA
    strcpy(destinazione->ptr->parola, "parola modificata in destinazione");

    printf("\nmemcpy, numero %d\n", memres->numero);
    printf("\nmemcpy, parola :%s\n", memres->ptr->parola);

    //as you can see from the output, memcpy doesn't make a copy of destinazione:
    //modifying destinazione->ptr->parola after the assignment affects what memres carries with it
    //So from the idea that I got, memcpy just creates the pointers to the originary structure

    free(origine->ptr->parola);
    free(origine->ptr);
    return 0;
}

More Related questions