free释放了一个结构体 但是它里面的指针却依然可以访问?? c语言
发布网友
发布时间:2022-05-18 19:27
我来回答
共5个回答
热心网友
时间:2023-10-26 12:53
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;
热心网友
时间:2023-10-26 12:54
只能说明你用的编译器对free()的处理有漏洞。我这里编译都通不过,删除free(test1)就可以了,输出是20 10。
热心网友
时间:2023-10-26 12:54
free()是释放堆。你的next指向的是栈的地址,当前作用域内,栈还有效,不会被释放
热心网友
时间:2023-10-26 12:55
对已释放的地址进行取值运算是一种未定义行为,编译器有可能会报错,也有可能不报错,但是你不能指望它能一直按你想的方式来运行。
你这里之所以可以显示为10,可以说是编译器的”慈悲“吧
热心网友
时间:2023-10-26 12:56
结构体内的指针无论是分配和释放空间都要独立进行,即使结构体分配了空间他也没有被分配空间