free释放了一个结构体 但是它里面的指针却依然可以访问?? c语言

代码如下:#include<stdio.h>#include<stdlib.h>structtest{inta;structtest*next;};intmain(){s... 代码如下:
#include <stdio.h>
#include <stdlib.h>

struct test
{
int a;
struct test *next;
};
int main()
{
struct test test0={10};
struct test *test1 = (struct test *)malloc(sizeof(struct test));
test1->a=20;
test1->next = &test0;
free(test1);
printf("%d %d",test1->a,(*test1->next).a);

}
输出test1->a为0 ,(*test1->next).a为10

说明结构体里的变量a已经被free释放掉了,而test1的指针next却还可以被访问
展开
 我来答
songqier
推荐于2018-05-06 · TA获得超过370个赞
知道小有建树答主
回答量:131
采纳率:0%
帮助的人:130万
展开全部
free函数,实际上做的事情不是真正的释放内存。
首先你要清楚,内存是由操作系统来管理的(操作包括分配、释放等)。
系统中的内存在c语言分配内存机制上被分为很多个块,c的底层代码用数据结构chunk来表示。chunk中有一个标志位,用来表示该内存块是否为待分配或者已分配状态。每一次调用malloc,这个标志位会被设置1(好像是1,记不太清楚了),调用free时被设置为0. 操作系统的内存管理机制会根据这个值来分配和释放内存。
也就是说调用free的时候,只是设置了这个标志位(当然还做了其他事,就你这个问题而言,只讨论这个),而内存还原封不动的在那里。所以,当你在系统真正释放这个内存之前再次访问这个地址,你会得到你想要的结果。
说明,“输出test1->a为0”,这个的原因可能是free的时候,设置chunk块的标志位时,覆盖了a的值。chunk数据结构中,第一个字节的前8位是标志位,后面还有24位也有各自的用处。具体是什么导致a的值为0的,你有兴趣的话,你可以自己去研究。可以去阅读linux的glibc源码。
"(*test1->next).a为10",就简单了。next偏移struct test所占内存的“头(head)”距离较远,free的时候的一些设置值的操作没有影响到,能访问到这个指针的值,并且test0还在函数栈中完整保留,自然就能访问到了。

P.S c/C++的malloc/free和new/delete都有这个特性,所以编程的时候要养成一个良好习惯,在调用free和delete的时候要将指针赋值为NULL,如:
free(ptr);
ptr=NULL;
或者
delete ptr;
ptr=NULL;
White_MouseYBZ
2013-01-14 · TA获得超过4万个赞
知道大有可为答主
回答量:2.1万
采纳率:82%
帮助的人:6573万
展开全部
只能说明你用的编译器对free()的处理有漏洞。我这里编译都通不过,删除free(test1)就可以了,输出是20 10。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
大侠在江湖飘
2018-10-22
知道答主
回答量:1
采纳率:0%
帮助的人:811
展开全部
free()是释放堆。你的next指向的是栈的地址,当前作用域内,栈还有效,不会被释放
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户

2013-01-14
展开全部
对已释放的地址进行取值运算是一种未定义行为,编译器有可能会报错,也有可能不报错,但是你不能指望它能一直按你想的方式来运行。
你这里之所以可以显示为10,可以说是编译器的”慈悲“吧
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
halron
2018-05-05
知道答主
回答量:18
采纳率:0%
帮助的人:6.4万
展开全部
结构体内的指针无论是分配和释放空间都要独立进行,即使结构体分配了空间他也没有被分配空间
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
收起 更多回答(3)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式