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却还可以被访问 展开
#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却还可以被访问 展开
5个回答
展开全部
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;
首先你要清楚,内存是由操作系统来管理的(操作包括分配、释放等)。
系统中的内存在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;
展开全部
只能说明你用的编译器对free()的处理有漏洞。我这里编译都通不过,删除free(test1)就可以了,输出是20 10。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
free()是释放堆。你的next指向的是栈的地址,当前作用域内,栈还有效,不会被释放
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
2013-01-14
展开全部
对已释放的地址进行取值运算是一种未定义行为,编译器有可能会报错,也有可能不报错,但是你不能指望它能一直按你想的方式来运行。
你这里之所以可以显示为10,可以说是编译器的”慈悲“吧
你这里之所以可以显示为10,可以说是编译器的”慈悲“吧
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
结构体内的指针无论是分配和释放空间都要独立进行,即使结构体分配了空间他也没有被分配空间
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询