看看这个C代码:
#include<stdio.h>
#include<stdlib.h>
int main(){
int *ptr_one;
ptr_one = (int *)malloc(sizeof(int));
if (ptr_one == 0){
printf("ERROR: Out of memory\n");
return 1;
}
*ptr_one = 25;
printf("%d\n", *ptr_one);
free(ptr_one);
printf("%d\n", *ptr_one);
return 0;
}
运行此代码时,它给出以下输出:
25
25
即使我释放了指针,为什么它仍给出25作为输出?
答案 0 :(得分:2)
详细了解undefined behavior(UB)。您的代码中包含一些内容(free
-d之后,不允许使用指针执行某些操作)。
即使我释放了指针,为什么它仍给出25作为输出?
是UB。你真倒霉成为scared。
阅读C11标准规范n1570。
您实际上不需要了解free
的工作原理(但是您需要了解如何使用它)。但是,它通常使用一些operating system特定的system call处理virtual address space。在Linux上,有许多C standard library实现-例如GNU glibc或musl-libc-是free software(因此您可以下载和研究他们的源代码),并且他们的malloc
有时会 变得更加虚拟用mmap(2)(或旧的sbrk(2))之类的系统调用来处理空间,而它们的free
有时 用munmap(2)释放一些空间。>
通常发生的情况是,C dynamic memory allocation在“大”和“小”存储区中的工作方式不同。对于小型区域,C库希望在以后的free
-s中重用先前的malloc
-d。它有时从OS中获取大量内存(使用mmap
),然后将其拆分为多个部分。当您free
一个小区域时,该区域会被简单地添加到一些片段集合中,以备将来malloc
使用。因此它仍然“存在”,但是使用的是UB(并且可以解释您正在观察的行为)。
valgrind实用程序是一个非常有用的工具,用于搜寻与内存相关的UB。
答案 1 :(得分:2)
使用free
时唯一发生的事情是,您告诉操作系统(或类似操作系统)您保证不再使用指针。函数free
将指针作为参数,而不是指向指针的指针,因此不能更改指针。