C语言中的浅拷贝和深拷贝

4jb9z9bj  于 2023-04-29  发布在  其他
关注(0)|答案(3)|浏览(182)

我试着在谷歌上搜索这个,但只有面向对象的语言弹出作为结果。
根据我的理解,浅拷贝是复制结构的某些成员。
假设一个结构体是

typedef struct node
{
    char **ok;
    int hi;
    int yep;
    struct node *next;
}node_t

复制char**将是一个浅拷贝
但复制整个链表将是一个深度复制?
我的想法是对的还是错的太远了?谢谢。

tzxcd3kk

tzxcd3kk1#

不。在这个特定的上下文中,浅复制意味着你将“引用”(指针,无论什么)复制到对象,并且这些引用或指针的后备存储是相同的,它是同一个内存位置的同一个对象。
相比之下,深层复制意味着复制整个对象(结构)。如果它有可以被浅复制或深复制的成员,您也可以对它们进行深复制。考虑以下示例:

typedef struct {
    char *name;
    int value;
} Node;

Node n1, n2, n3;

char name[] = "This is the name";

n1 = (Node){ name, 1337 };
n2 = n1; // Shallow copy, n2.name points to the same string as n1.name

n3.value = n1.value;
n3.name = strdup(n1.name); // Deep copy - n3.name is identical to n1.name regarding
                           // its *contents* only, but it's not anymore the same pointer
3qpi33ja

3qpi33ja2#

据我所知,在C语言中并没有真正的“浅”复制或“深”复制。
如果从OOP的Angular 考虑,您可能会发现一些答案是正确的,但会产生误导
在C中,当使用'='运算符时,只有一种内置的复制技术,即数据复制
C将结构的元数据存储在RAM中,并确保一旦创建了结构,它的大小不会改变,并且可以从分配的内存的特定部分访问变量
当使用'='运算符时,它只将存储在结构中的数据逐位复制到另一个结构中,因为它们具有相同的大小。
结构中静态分配的变量和数组具有固定的大小,并完全存储在结构的分配内存中。动态分配的变量都是指针。指针变量是静态分配的内存,相当于无符号long int。
当你在一个结构体中有一个指针时,它只存储地址,它指向的内存,也就是动态分配的位置,结构体实际上没有任何关于指针指向内存的信息。是操作系统和编译器跟踪动态分配的内存。
例如:

#include <stdio.h>
#include<stdlib.h> 
struct Foo
{
    int value_1;
    int *value_2;
    int value_3[3];
}S1,S2;

 
void print(struct Foo S)
{
    printf("%d,%d,%d,%d,%d\n",S.value_1,*(S.value_2),S.value_3[0],S.value_3[1],S.value_3[2]);
}
int main()
{
    S1.value_1=43;
    S1.value_2=(int*)malloc(sizeof(int));
    *(S1.value_2)=55;
    S1.value_3[0]=101;
    S1.value_3[1]=102;
    S1.value_3[2]=103;
    printf("S1:");
    print(S1);
    S2=S1;
    printf("S2:");
    print(S2);
    S1.value_1=4300;
    *(S1.value_2)=5500;
    S1.value_3[0]=10100;
    S1.value_3[1]=10200;
    S1.value_3[2]=10300;
    printf("\nAfter Altering\n");
    printf("S1:");
    print(S1);
    printf("S2:");
    print(S2);
    return 0;
}

输出:

S1:43,55,101,102,103
S2:43,55,101,102,103

After Altering
S1:4300,5500,10100,10200,10300
S2:43,5500,101,102,103

简而言之,在C中复制有两种行为:

  • 对于动态分配的变量,也就是指针,使用浅拷贝
  • 对于静态分配的变量或数组,使用深度复制

此外,如果你要创建一个指向一个结构变量(不是新分配的)的指针,只要内存在作用域内,它就像一个引用一样,使用普通变量或结构指针所做的任何更改都会导致两者都反映相同。

int a=20;
Foo S1,*S2;
S2=&S1;
S1.value1=10;
S1.value2=&a;
S1.value3[0]=101;
S1.value3[1]=102;
S1.value3[2]=103;
S2->value1=15;

在上面的例子中,我们尝试操作哪个值并不重要,因为两者都影响相同的物理内存
将指针复制为指针/地址时,会发生浅层复制。将值从指针复制到另一个变量/指针时,其行为类似于在两个非指针之间进行复制

c9x0cxw0

c9x0cxw03#

复制构造函数用于用同一类的先前创建的对象初始化新对象。默认情况下编译器写的是浅拷贝。浅拷贝在不涉及动态内存分配时工作良好,因为当涉及动态内存分配时,两个对象将指向堆中的相同内存位置,因此为了消除这个问题,我们编写了深拷贝,因此两个对象在内存中都有自己的属性副本。为了阅读完整示例和解释的细节,您可以查看本文中有关Shallow and Deep copy constructors之间差异的部分。

相关问题