C语言 结构体复制后free的问题
背景:相互兼容的结构体间(最普通的就是同一类型的结构体)简单赋值(就是“=”),以C9x的标准,是可以直接直接赋值的
情境1
假设有两个一样的结构体
typedef struct SS {
int a;
int b;
} SSS;
SSS *s1, *s2;
s1 = malloc (sizeof(struct SS));
s1->a = 23;
s1->b = 24;
s2 = malloc (sizeof(struct SS));
s2 = s1;
free(s1);
printf ("%d %d", s2->a, s2->b);
s2 = s1
这样赋值的话,语句printf ("%d %d", s2->a, s2->b);
会导致访问已经free的内存吗?
情境2
typedef struct A {
int a;
int b;
} AA;
typedef struct B {
int c;
struct A stra;
} BB;
struct B *new_b1, *new_b2;
new_b1 = malloc(sizeof(struct B));
new_b2 = malloc(sizeof(struct B));
new_b1->c = 23;
new_b1->stra.a = 24;
new_b1->stra.b = 25;
new_b2->c = 26;
new_b2->stra = new_b1->stra;
free(new_b1);
printf ("%d %d", new_b2->stra.a, new_b2->stra.b); //如果这样,printf访问的是已经free的空间吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
结构体赋值和指针赋值是两个不同的概念。在你的例子里,s1, s2 都是指针,那么 s2 = s1是指针赋值,赋值之后s2,s1就之指向同样的内存地址,所以会导致访问已经free的内存。结构体赋值是会把各个member的值copy的。
补充一下:
我们可以看看编译器是怎么实现结构体赋值的。比如:
下面是clang生成的llvm IR.
这里有两个
llvm.memcpy
, 第一个是给a
赋值,第二个是给aa
赋值。所以C编译器仅仅是做了一个memcpy
,把a
的内容拷贝到aa
所在的内存。所以相互兼容的结构体间可以这样赋值,但是这样做有没有意义就要看具体情况了吧。你说的第二种情景,其实就是结构体赋值,因为
new_b2->stra
不是指针。所以不会访问free掉的内存。下面的例子更可以说明问题:
再看
*s2 = *s1
和s2 = s1
LLVM代码:*s2 = *s1
赋值的时候,LLVM是把s1
指向的内容memcpy
到s2
指向的内存。这里LLVM要先derefence这两个指针。而s2 = s1
赋值的时候不用memcpy
而是直接把s1的内容store到s2.希望这个例子能说明这两种赋值的区别。
这里有个讨论帖可以看一下
http://bbs.csdn.net/topics/110160458