我在这个网站上读到了许多关于如何在C中复制结构的问题。我一直在玩一些代码,试图理解‘浅’复制(其中新的结构只是被分配到第一个结构的内存地址的指针)和‘深度’复制(其中数据被逐个成员复制到一个新的内存块)之间的区别。
我创建了以下代码,假设它将显示“浅”复制行为:
#include <stdio.h>
struct tester
{
int blob;
int glob;
char* doob[10];
};
int main (void)
{
//initializing first structure
struct tester yoob;
yoob.blob = 1;
yoob.glob = 2;
*yoob.doob = "wenises";
//initializing second structure without filling members
struct tester newyoob;
newyoob = yoob;
//assumed this line would simply copy the address pointed to by 'yoob'
//printing values to show that they are the same initially
printf("Before modifying:\n");
printf("yoob blob: %i\n", yoob.blob);
printf("newyoob blob: %i\n", newyoob.blob);
//modifying 'blob' in second structure. Assumed this would be mirrored by first struct
newyoob.blob = 3;
//printing new int values
printf("\nAfter modifying:\n");
printf("yoob blob: %i\n", yoob.blob);
printf("newyoob blob: %i\n", newyoob.blob);
//printing memory addresses
printf("\nStruct memory addresses:\n");
printf("yoob address: %p\n", &yoob);
printf("newyoob address: %p\n", &newyoob);
}运行输出:
Before modifying:
yoob blob: 1
newyoob blob: 1
After modifying:
yoob blob: 1
newyoob blob: 3
Struct memory addresses:
yoob address: 0x7fff3cd98d08
newyoob address: 0x7fff3cd98cb0这段代码是像它所显示的那样创建一个深拷贝,还是我误解了这里发生的事情?
发布于 2016-03-22 17:30:35
浅拷贝问题与深复制问题仅与指针有关。给定一个类型的struct foo
struct foo a = /* initialize */;
struct foo b = a;a中的所有值都复制到b中。它们不是同一个变量。
但是,有了指针:
struct foo *p = calloc(1, sizeof *p);
struct foo *q = p;q现在指向与p相同的内存;没有发生任何复制(一旦获得freed,就会有悬挂指针的风险)。这是一个指针别名。为了做一个浅显的拷贝,人们会做:
struct foo *p = calloc(1, sizeof *p);
/* assign to p's fields... */
struct foo *q = calloc(1, sizeof *q);
*q = *p;现在,q具有与p相同的字段值,但指向不同的内存块。
深拷贝需要额外的努力;结构中的任何指针都必须被遍历,并且它们的内容也必须被复制。有关一个很好的解释,请参见this post。
发布于 2016-03-22 17:23:26
当您使用newyoob = yoob;时,编译器会创建代码来为您复制结构。
关于复制的一个重要的注意事项:这是一个浅薄的。这意味着,如果您有一个包含指针的结构,那么只有实际的指针才会被复制,而不是它们所指向的,所以在复制之后,您将有两个指针指向相同的内存。
发布于 2016-03-22 17:39:05
你的“肤浅拷贝”的概念是错误的。密码
newyoob = yoob; 实际上正在创建一个从yoob到newyoob的shallow copy。您的变量yoob和newyoob是单独的内存分配。
如果是你干的
struct tester* newyoob = &yoob;然后newyoob和yoob是“相同的”--但同样,引用相同内存区域的两个变量不被认为是副本。
https://stackoverflow.com/questions/36161014
复制相似问题