Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何创建数组的浅层副本并将该副本存储在结构中_C_Arrays_Memcpy_Shallow Copy - Fatal编程技术网

C 如何创建数组的浅层副本并将该副本存储在结构中

C 如何创建数组的浅层副本并将该副本存储在结构中,c,arrays,memcpy,shallow-copy,C,Arrays,Memcpy,Shallow Copy,我有一个结构 typedef struct Heap { int length; int size; int A[]; } Heap; 我试图创建给定数组的浅层副本并将其存储在此结构中。这样,当阵列被更改或元素被交换时,这将镜像到原始阵列中 Heap * build_max_heap(int A[], int length) { Heap * heap = malloc(sizeof(Heap) + length*sizeof(int *)); *hea

我有一个结构

typedef struct Heap {
    int length;
    int size;
    int A[];
} Heap;
我试图创建给定数组的浅层副本并将其存储在此结构中。这样,当阵列被更改或元素被交换时,这将镜像到原始阵列中

Heap * build_max_heap(int A[], int length) {
    Heap * heap = malloc(sizeof(Heap) + length*sizeof(int *));
    *heap = (Heap) { length, length };
    memcpy(heap->A, A, length*sizeof(int *));

    /*
    for(int i = floor(((heap->length)-1)/2); i >= 0; --i) {
        max_heapify(heap, i);
    }
    */

    return heap;
}

int main() {
    int A[] = {0, 3, 7, 61, 3, 40, 4, -1, 8, 10};

    Heap * heap = build_max_heap(A, 10);

    A[0] = 100;

    for(int i = 0; i < 10; ++i) {
        printf("%i, ", A[i]);
    }

    printf("\n");

    for(int i = 0; i < 10; ++i) {
        printf("%i, ", heap->A[i]);
    }

    return 0;
}
我的预期结果是

100, 3, 7, 61, 3, 40, 4, -1, 8, 10,
100, 3, 7, 61, 3, 40, 4, -1, 8, 10,
类似地
heap->A[0]=100应具有相同的效果。我也不确定
length*sizeof(int*)
是否正确,或者应该改为
length*sizeof(int)
,但是我想回答前者可以解决这个问题


浅层复制相当于复制引用而不是值。但是,这需要以稍微不同的方式定义结构:

typedef结构堆{
整数长度;
整数大小;
int*A;
}堆;
这样,数组
A
的值就不会立即包含在结构之后,我们可以自由地向它分配任何指针。然后,我们将堆初始化为:

Heap*build\u max\u Heap(int A[],int length){
Heap*Heap=malloc(sizeof(Heap));
*heap=(heap){length,length,A};
/*…heapify代码等*/
返回堆;
}

但是您必须谨慎地使用它——这意味着如果您从一个堆中创建两个堆,它们将相互影响。创建副本仍然是最佳实践。

您的想法很好,但实现效果并不理想

typedef struct Heap {
    size_t length;
    size_t size;
    int A[];
} Heap;

Heap *build_max_heap(int *A, size_t length) {
    Heap * heap = malloc(sizeof(*heap) + length*sizeof(*A));
    *heap = (Heap) { length, length };
    memcpy(heap-> A, A, length*sizeof(*A));

    /* another stuff */

    return heap;
}

这种数据位于结构末尾的结构非常常用。我只允许一次分配(一次免费),而不是两次。它也更有效,因为它不需要读取指针
A
,然后取消对它的引用。

很好,这允许我进行适当的排序。答案实际上是错误的。它不创建数组的副本,只保存数组的引用-数据不会被复制、保存或删除mirrored@P__J__-OP要求浅拷贝,以允许就地更改。浅层副本是引用的副本,而不是数据的副本。此代码不会导致OP请求的预期输出。它打印
0,3,7,61,3,40,4,-1,8,10,
,这是OP试图避免的。虽然如果您想进行深度复制,使用
sizeof(*A)
sizeof(int)
而不是
size(int*)
是正确的。但是sizeof(type)被认为是不好的做法。使用非类型对象在应该使用的位置使用两次
sizeof(int*)
typedef struct Heap {
    size_t length;
    size_t size;
    int A[];
} Heap;

Heap *build_max_heap(int *A, size_t length) {
    Heap * heap = malloc(sizeof(*heap) + length*sizeof(*A));
    *heap = (Heap) { length, length };
    memcpy(heap-> A, A, length*sizeof(*A));

    /* another stuff */

    return heap;
}