我知道它从堆中释放内存。但是程序如何知道内存被释放(或没有释放)。如果我必须猜测的话,程序内存中的某个地方有某种“可用内存列表”。如果是这样,该列表的结构如何?是由程序管理还是由操作系统管理?
我创建了一个简单的程序来尝试找出发生了什么:
#include <iostream>
int main () {
int* ptr = new int;
*ptr = 0xFFFFFFFF;
std::cout << ptr << std::endl; //some random 64-bit address
std::cout << *ptr << std::endl; //-1
delete ptr;
std::cout << ptr << std::endl; // always 0x0000000000008123
std::cout << *ptr << std::endl; // Exception thrown: read access violation.
return 0;
}
删除操作符之前ptr指向的内存位置:
相同的内存位置,但在删除运算符之后:
为什么旧的内存位置删除后总是充满0xDDDDDDDD?是不是表示内存被释放的标志?如果它已经在假设的“可用内存列表”中跟踪它,为什么还要这样做呢?我的意思是写入内存需要一些努力(即使在这个例子中可以忽略不计),为什么不把它留在那里,直到有其他东西覆盖它。
虽然最初ptr指向某个随机地址,但是在删除操作之后,它始终指向0x0000000000008123。是不是也是一个标志,表明指针现在指向了一个不可访问的内存块?
(我在 Windows 10 64 位操作系统上使用 Visual Studio 2022)
仅仅一些好文章的链接也会有帮助。谢谢你。
为什么旧的内存位置删除后总是填满0xDDDDDDDD?
您的平台的调试版本在内存释放后将
memset
设为 0xDD。
标准中没有规定。这是特定于您的平台的实施细节。
q.v. DDDDDDDD
值的
幻数。
是不是内存被释放的标志?
不,这是一个帮助调试的标记。
如果它已经在假设的“可用内存列表”中跟踪它,为什么还要这样做呢?
帮助调试很麻烦。
我的意思是写入内存需要一些努力(即使在这个例子中可以忽略不计),为什么不把它留在那里直到有其他东西覆盖它。
它可以帮助调试。