如何使用双精灵执行深层复制?

时间:2016-12-16 19:25:47

标签: c pointers memcpy

Question阅读。

在下面的代码中,List使用的Stack依次由preOrderTraversal()使用root树,没有递归但使用显式堆栈,       / * list.h * /       typedef struct List {

    void **array;
    int lastItemPosition;
    int size;
  }List;

  #define INITIAL_LIST_SIZE 50

List *createList(List *list, Op opType){

  List *lptr = (List *)malloc(sizeof(List));
  void *array = NULL;
  if(opType == CREATE_NEW_LIST){

    array = malloc(INITIAL_LIST_SIZE*sizeof(void*));
    lptr->array = &array;
    lptr->array = memset(lptr->array, 0, INITIAL_LIST_SIZE*sizeof(void *));
    lptr->lastItemPosition = -1;
    lptr->size = INITIAL_LIST_SIZE;
  }else if(opType == DOUBLE_THE_LIST){

    array = malloc(2*(list->size)*sizeof(void *));
    lptr->array = &array;
    lptr->array = memcpy(lptr->array, list->array, list->size*sizeof(void*));
    lptr->lastItemPosition = list->lastItemPosition;;
    lptr->size = 2*(list->size);
  }else if(opType == HALF_THE_LIST){

    array = malloc(((list->size)/2)*sizeof(void *));
    lptr->array = &array;
    lptr->array = memcpy(lptr->array, list->array, (list->size/2)*sizeof(void *));
    lptr->lastItemPosition = list->lastItemPosition;;
    lptr->size = (list->size)/2;
  }

  return lptr;

}

void insertItem(List *, void *, int);
void *deleteItem(List *, int);
List* createList(List *, Op);
/* Stack.h */
#include"list.h"

typedef struct Stack{

  List *arrayList;
}Stack;

void push(void *);
void *pop();
void*top();

WRT,

lptr->array = memcpy(lptr->array, list->array, list->size*sizeof(void*));

memcpy正在传递双指针。双指针是指向单个指针的单个指针,因此可以将其传递给需要void指针的函数,但是,void*的实际数组副本不起作用

因为我实际上需要复制void*的数组。如果memcpy被调用,比如,

lptr->array = memcpy(*(lptr->array), *(list->array), list->size*sizeof(void*));

然后,

memcpy是否成功执行了复制操作?如何进行深层复制?

1 个答案:

答案 0 :(得分:1)

您现有的memcpy语句会复制void *个值的数组。这些void *中的每一个都可能指向不同的内存块,具有一些任意内容。 memcpy对任意内容不做任何事情:你所做的就是创建这些块的地址列表的副本,而不是复制块本身。

我们很难看到你如何对底层内容,我们在这里看到的代码片段以及包括复制它的内容做任何事情。这是因为没有每个void *'所指向的内容的类型或大小的记录。

你提出的建议:

memcpy(*(lptr->array), *(list->array), list->size*sizeof(void*))

因多种原因无效。它要求memcpy采用第一个 void *值(不是其他任何一个 - 这是一个问题),并查看第一个指针所指向的底层内存块。它将一定量的内存从源块复制到目标块。但是您没有提到为新目标块分配任何新内存(从而更改目标void *本身的值),因此源和目标可能是相同的地址。那是另一个问题。此外,它使用了错误的大小(void *的整体列表的大小,而不是所讨论的内存块的大小)。那是另一个问题。

通过一次通话无法实现您想达到的目标。您的void * 可能(由我们在此处看不到的代码定义)指向单个连续内存块的连续部分 - 在这种情况下,单个memcpy似乎可以正常工作“意外地”。但据我们所知,他们也可能不会那样安排。它们可能是在整个地方单独分配的内存块。如果是这样,你将需要单独处理每一个:在复制该块之前,遍历指针数组,并为每个malloc新空间复制相关块。当然,无论是分配还是复制,您都需要记录每个块的大小。