【问题标题】:Copying a pointer-containing struct in C - how does it work?在 C 中复制包含指针的结构 - 它是如何工作的?
【发布时间】:2021-01-04 18:21:48
【问题描述】:

我接到了一个任务,要告诉我打印的内容是什么,但我什么都不懂。
为什么在//***OUTPUT #1*** 的行中打印

first array is:  
0 1 2 30

而不是

first array is:  
0 1 2 3

如果他们写T2 = T1,这意味着他们指向同一个地址,并且对T2所做的所有更改都将与对T1的更改相同?

我以为不是这样,因为它们是 2 个变量,T2 会将数据复制到 T1 中,但会复制到新地址中。

代码如下:

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

typedef struct myArray
{
    int *iArr;
    int size;
    char name[10];
}MyArray;

void printArray(MyArray T);

int main()
{
    MyArray T1,T2;
    int i;
    T1.size = 4;
    T1.iArr = (int *) calloc(T1.size, sizeof(int));
    strcpy(T1.name, "first");
    for (i=0; i<T1.size;i++)
    {
        T1.iArr[i] = i;
    }
    printArray(T1);
    T2 = T1;
    T2.iArr[3] = T1.iArr[3]*10;
    T2.size=2;
    printArray(T1); //***OUTPUT #1***
    printArray(T2);
    strcpy(T2.name, "second");
    T2.iArr = (int *) calloc(T2.size, sizeof(int));
    for(i=0;i<T2.size;i++)
    {
        T2.iArr[i] = -i;
    }
    printArray(T1);
    printArray(T2);
    return 0;
}

void printArray(MyArray T)
{
    int i;
    printf("%s array is:\n",T.name);
    for(i=0;i<T.size;i++)
    {
        printf ("%d ",T.iArr[i]);
    }
    printf ("\n");
}

【问题讨论】:

  • 问题陈述不可读。请添加一些大小写、标点符号和格式。
  • T2.iArr == T1.iArr,所以虽然 T1 和 T2 是不同的变量,但它们每个都包含一个指向同一个内存位置的指针。
  • 所以如果我将 T2.name 更改为“test”,T1.name 也应该受到影响?
  • 分配给T2.iArr[3]时,与T1.iArr[3]相同。稍后您将 T2.iArr 更改为指向不同的位置。

标签: arrays c string struct


【解决方案1】:

在这里,您将所有值从 T1 的成员复制到 T2,即所谓的“浅”复制。

T2 = T1;

这包括指针内部的地址,浅。 IE。两者都引用相同的内存区域。
在这两个都引用的单一内存中,您在此处写入的值是已经存在的值的 10 倍。

T2.iArr[3] = T1.iArr[3]*10;

在此之前和之后,两个指针都指向同一个指针,因此您将通过这两个指针读取“30”。 你在这里做什么。

printArray(T1); //***OUTPUT #1***
printArray(T2);

对于没有表现出观察到的行为的“深层”副本,您必须创建指向内存的新副本(即再做一个calloc())。

所以:

如果他们写 T2 = T1 ,这意味着他们指向同一个地址,并且对 T2 所做的所有更改都将与对 T1 的更改相同?

是的,没错。

但是

我认为不是这样,因为它们是 2 个变量,所以 T2 将复制 T1 中的数据,但复制到一个新地址中

是(浅)和否(不深)。
是的,T1 中的所有值都被复制到 T2 中的新内存中,但两者中的指针包含相同的值/地址。
所以不,他们指向的是同一个内存,你最初从第一个 calloc() 获得的内存。

是的,两个指针(驻留在不同的内存中)指向同一个内存。不,不是动态分配的不同内存部分。

这不会改变,直到你这样做

T2.iArr = (int *) calloc(T2.size, sizeof(int));

您在这里接近完成深层复制,尽管使用不同的值

for(i=0;i<T2.size;i++)
{
    T2.iArr[i] = -i; // different values
  //T2.iArr[i] = T1.iArr[i]; // deep copy variant, keeping the "30"

}

【讨论】:

    猜你喜欢
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-07
    • 2016-10-19
    • 2019-07-06
    相关资源
    最近更新 更多