在C或C++等语言中,结构体(Struct)是一种用户自定义的数据类型,它允许将不同类型的数据项组合成一个单一的类型。对于结构体的拷贝,存在深拷贝(Deep Copy)和浅拷贝(Shallow Copy)两种概念,这两种拷贝方式在处理结构体(特别是包含指针成员的结构体)时尤为重要。
浅拷贝(Shallow Copy)
浅拷贝仅仅复制了结构体中的值,如果结构体中含有指针成员,那么浅拷贝会复制指针的值(即内存地址),而不会复制指针所指向的内存区域。这意味着,原结构体和拷贝后的结构体中的指针成员会指向同一块内存区域。因此,如果通过其中一个结构体的指针成员修改了这块内存区域,那么这种修改对另一个结构体也是可见的。
深拷贝(Deep Copy)
深拷贝不仅复制了结构体中的值,还复制了结构体中所有指针成员所指向的内存区域。这意味着,原结构体和拷贝后的结构体是完全独立的,对其中一个结构体的修改不会影响到另一个。
假设我们有一个结构体,它包含一个整型和一个指向整型的指针
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int value;
int *ptr;
} MyStruct;
// 浅拷贝函数
MyStruct shallowCopy(MyStruct src)
{
MyStruct dst = src; // 直接赋值,为浅拷贝
return dst;
}
// 深拷贝函数
MyStruct deepCopy(MyStruct src)
{
MyStruct dst;
dst.value = src.value;
dst.ptr = (int *)malloc(sizeof(int)); // 为新指针分配内存
if (dst.ptr != NULL)
{
*dst.ptr = *src.ptr; // 复制指针指向的内容
}
return dst;
}
int main()
{
MyStruct orig = {10, malloc(sizeof(int))};
*orig.ptr = 20;
MyStruct shallow = shallowCopy(orig);
MyStruct deep = deepCopy(orig);
*shallow.ptr = 30; // 修改浅拷贝中的指针指向的值
printf("Orig value: %d, pointer value: %d\n", orig.value, *orig.ptr); // 预期输出: 10, 30
printf("Shallow value: %d, pointer value: %d\n", shallow.value, *shallow.ptr); // 预期输出: 10, 30
*deep.ptr = 40; // 修改深拷贝中的指针指向的值
printf("Orig value: %d, pointer value: %d\n", orig.value, *orig.ptr); // 预期输出: 10, 30
printf("Deep value: %d, pointer value: %d\n", deep.value, *deep.ptr); // 预期输出: 10, 40
// 清理内存
free(orig.ptr);
free(shallow.ptr); // 注意:这里不需要释放,因为shallow.ptr和orig.ptr指向同一块内存
free(deep.ptr);
return 0;
}
运行结果为
- 浅拷贝只复制了结构体的值,如果结构体中包含指针,则指针的值(即内存地址)会被复制,但指针指向的内存区域不会被复制。
- 深拷贝复制了结构体的值,并且为结构体中所有指针成员所指向的内存区域分配了新的内存,并复制了内容。这样,原结构体和拷贝后的结构体在内存中是独立的。