我有这个简单的测试 C 程序,它泄漏了 4 个字节的内存:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int* x = malloc(sizeof(int));
printf( "Address: %p\n", x);
return 0;
}
我用gcc -o leak leak.c
编译它,然后运行它:
$ leak
Address: 0x55eb2269a260
然后我创建另一个测试 C 程序来尝试释放泄漏的内存:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
void *addr = (void*)0x55eb2269a260;
printf( "Trying to free address: %p\n", addr);
free(addr);
return 0;
}
我用 gcc -o myfree free.c
编译它然后运行它:
$ myfree
Trying to free address: 0x55eb2269a260
Segmentation fault (core dumped)
这里发生了什么?为什么无法释放泄漏的内存?
最佳答案
假设我们谈论的是类 Unix 操作系统(这也适用于 Windows 和大多数其他现代操作系统)...
What is happening here? Why is it not possible to free the leaked memory?
首先:每个正在运行的进程都有自己的虚拟地址空间(或VAS
)。此 VAS
是操作系统必须在不同进程之间布置和组织物理内存的一种方式。在 32 位处理器上,它的范围从 0x0 到 0xFFFFFFFF,包含进程的所有内存 - 它的代码、静态数据、堆栈、堆等,它们都在进程 VAS
中。虚拟地址(或 VA
)是虚拟地址空间内的特定地址。
当您使用 malloc
分配内存时,系统将在进程堆上搜索有效的未分配内存,如果找到,则返回它的指针(即 malloc
本质上返回一个虚拟地址)。
进程结束后,它的VAS
会被操作系统自动“释放”,这样内存就不再有效,或者就此分配。除此之外,每个进程都有自己的虚拟地址空间。您不能使用另一个进程的 VA
(虚拟地址)直接访问进程 VAS
(虚拟地址空间) - 通过这样做,您实际上最终做的是尝试在您的示例中访问正在运行的进程中的 VA
很可能会导致未处理的 ACCESS_VIOLATION
异常并使进程崩溃。
关于c - 是否可以从另一个进程中释放泄漏的内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57571539/