2013-02-17 11 views
5

Potrzebuję twojej pomocy!głęboka kopia struktury z Point Point w C

Lubię skopiować struct tak:

typedef struct PackageObject_s { 
    long **vertex;   // vertices 
    long num_vertex;  // count of vertices 
    long objectType;  // 
    REAL r;    // 
    long bottom[3];  // bounding box bottom vector 
    long top[3];   // bounding box top vector 
    long *start;   // 
    REAL coverage;  // 
} PackageObject __attribute__ ((aligned)); 

próbuję go tak:

static inline void PackageObject_copy(PackageObject *dst, const PackageObject *src) { 

    dst->num_vertex = src->num_vertex; 
    dst->objectType = src->objectType; 
    dst->r   = src->r; 
    vec_assign3l(dst->bottom, src->bottom); 
    vec_assign3l(dst->top, src->top); 

    // TODO copy **vertex ??? 

    dst->coverage = src->coverage; 
    dst->coverage = src->coverage; 
} 

Jak mogę rozwiązać ten problem?

Z góry dziękujemy za pomoc!

AKTUALIZACJA - moje rozwiązanie dla deepcopy z vertex - thx za wszelką pomoc:

dst->vertex = (long *)malloc(dst->num_vertex * 3 * sizeof(long)); 
for (long i=0; i < src->num_vertex; i++) { 
    dst->vertex[i] = (long)malloc(3*sizeof(long)); 
    memcpy(dst->vertex[i],src->vertex[i],3 * sizeof(long)); 
} 
+0

musisz skopiować ** wierzchołek?! – amrfaissal

+0

Dzięki za wszystkie odpowiedzi (@Sparky, @Foon, @eznme). Mam to :-)
'dst-> vertex = (long *) malloc (dst-> num_vertex * 3 * sizeof (long)); for (long i = 0; i < src-> num_vertex; i ++) {dst-> vertex [i] = (long) malloc (3 * sizeof (long)); memcpy (dst-> vertex [i], src-> vertex [i], 3 * sizeof (long)); } ' – romi1013

Odpowiedz

2

mam zamiar założyć, że wierzchołki nie są dzielone między obiektami. Oznacza to, że należą one do omawianej struktury.

Istnieją dwa podstawowe przypadki do rozważenia:

1. Copying into a new object 
2. Copying into an existing object 

Kopiowanie do nowego obiektu jest bardzo proste.

1a. Allocate space for <num_vertex> pointers. 
1b. Allocate space for each vertex. 
2a. Copy <num_vertex> pointers from source to destination. 
2b. Copy <num_vertex> vertices from source to destination. 

Kopiowanie do istniejącego obiektu jest taka sama jak kopiowanie do nowego obiektu, z wyjątkiem, że trzeba wykonać następujące czynności jako pierwszy.

0a. Loop through each element of <vertex> and free the vertex. 
0b. Free the array of vertex pointers. 
1. Follow the steps for copying into a new object. 

Mam nadzieję, że to pomoże.

2

odpowiedź oryginalny:

Zakładając punkty wierzchołków do tablicy wierzchołków, a każdy Vertice zawiera 3 long (x , y, z):

dst->vertex = (long **)malloc(dst->num_vertex * 3 * sizeof(long); 
memcpy(dst,src,dst->num_vertex * 3 * sizeof(long)); 

Aktualizacja ponieważ zdałem sobie sprawę, że to może działać, ale nie jest czysty lub szczególnie bezpieczne Jak już wspomniano w komentarze, kod byłoby czystsze jeśli miał

typedef struct vertextag { 
    long x; 
    long y; 
    long z; 
} vertex_type; 

A potem zrobił: dst-> wierzchołek = (vertex_type *) malloc (dst-> num_vertex * sizeof (vertex_type); memcpy (dst, src, dst-> num_vertex * sizeof (vertex_type));

+0

Przeglądając niektóre z pozostałych odpowiedzi, nie myślałem o dwóch przypadkach. W tej odpowiedzi założono, że tablica wierzchołków jest unikatowa dla każdego obiektu (lub nie trzeba jej pogłębiać). Zakłada się także, że dst jest zupełnie nowym wskaźnikiem (ale wskazuje na poprawny zestaw pamięci, który albo zostanie utworzony lub utworzony na stosie); jeśli to nie jest zupełnie nowy obiekt, powinieneś pójść z podejściem Sparky'ego. Zauważ, że powinieneś sprawdzić, czy dst == src, jeśli dst nie ma gwarancji, że jest całkiem nowym obiektem lub przynajmniej dokumentuje go w funkcji, która tego nie robi, ponieważ w przeciwnym razie wyciekniesz z pamięci. – Foon

+0

Twój kod prawdopodobnie byłby czystszy, gdybyś miał strukturę vertex_type {long x, long y, long z)}, której używałbyś zamiast długiego [3] dla obwiedni i używałby jako * vertex_type zamiast long **; w tym przypadku zrobiłbyś (vertex_type *) malloc (dst-> num_vertex * sizeof (vertex_type); – Foon

+0

To prawda, tablica wierzchołków jest unikalna dla każdego obiektu Każdy obiekt ma wierzchołki num_vertex Każdy wierzchołek jest współrzędną 3D (długi) .Jeżeli twoje pierwsze rozwiązanie nie działa, jeśli zmienię wierzchołek, zmienię go za pomocą tego rozwiązania w obu obiektach. – romi1013

1

To zależy od tego, czy tablica wierzchołków powinna należeć do obiektu, który próbujesz skopiować, czy też jest współużytkowana przez wiele obiektów. Oba podejścia są stosowane w praktyce, w zależności od sytuacji (konieczne jest skopiowanie macierzy, jeśli wierzchołki mogą być zmienione oddzielnie dla obiektu kopiowania). Musisz wybrać, który z nich ma sens dla tworzonej aplikacji.

Jeśli tablica może być współużytkowana przez obiekty wskazujące na nią, po prostu skopiuj wskaźnik.

dst->vertex = src->vertex; 

Jeśli każdy przedmiot ma swoje wierzchołki (więc może być zmieniona oddzielnie dla kopiowanego obiektu) następnie trzeba przeznaczyć i kopia tablicy i miejsce, w którym przechowywany jest wskaźnik i ustawić wskaźnik do tego miejsca do obiektu kopiowania.

long* vertexCopy = malloc(howmanybytes); 
memcpy(vertexCopy, *src->vertex, howmanybytes); 
long** holder = malloc(sizeof(void*)); 
holder[0] = vertexCopy; 
dst->vertex = holder; 
Powiązane problemy