Глубокая копия структуры с указателем в C

Мне нужна ваша помощь!

Мне нравится копировать такую ​​структуру:

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));

Я пытаюсь это так:

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;
}

Как я могу решить это?

Заранее спасибо за вашу помощь!!

ОБНОВЛЕНИЕ - мое решение для глубокой копии vertex - спасибо за помощь:

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)); 
}

3 ответа

Решение

Я собираюсь предположить, что вершины не разделяются между объектами. То есть они принадлежат к рассматриваемой структуре.

Есть два основных случая для рассмотрения:

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

Копировать в новый объект просто.

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.

Копирование в существующий объект во многом аналогично копированию в новый объект, за исключением того, что сначала нужно сделать следующее.

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.

Надеюсь это поможет.

Оригинальный ответ:

Предполагая, что вершина указывает на массив вершин, и что каждая вершина содержит 3 long (x,y,z):

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

Обновление, потому что я понял, что это может сработать, но это не чисто или особенно безопасно. Как я уже упоминал в комментариях, код будет чище, если

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

И затем сделал: dst->vertex = (vertex_type *)malloc(dst->num_vertex * sizeof(vertex_type); memcpy(dst,src,dst->num_vertex * sizeof(vertex_type));

Это зависит от того, должен ли массив вершин принадлежать объекту, который вы пытаетесь скопировать, или он используется несколькими объектами. Оба подхода используются на практике, в зависимости от ситуации (массив должен быть скопирован, если вершины могут быть изменены для объекта копирования отдельно). Вы должны выбрать, какой из них имеет смысл для приложения, которое вы разрабатываете.

Если массив может совместно использоваться объектами, указывающими на них, просто скопируйте указатель.

dst->vertex = src->vertex;

Если у каждого объекта есть свои вершины (так что они могут быть изменены отдельно для скопированного объекта), тогда вы должны выделить и скопировать массив и место, где хранится указатель, и установить указатель на это место в объекте копирования.

long* vertexCopy = malloc(howmanybytes);
memcpy(vertexCopy, *src->vertex, howmanybytes);
long** holder = malloc(sizeof(void*));
holder[0] = vertexCopy;
dst->vertex = holder;
Другие вопросы по тегам