在C++中,删除运算符实际上是如何工作的? (在记忆层面)

问题描述 投票:0回答:1

我知道它从堆中释放内存。但是程序如何知道内存被释放(或没有释放)。如果我必须猜测的话,程序内存中的某个地方有某种“可用内存列表”。如果是这样,该列表的结构如何?是由程序管理还是由操作系统管理?

我创建了一个简单的程序来尝试找出发生了什么:

#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指向的内存位置:

memory location pointed by ptr

相同的内存位置,但在删除运算符之后:

That same memory location but after the delete operator

为什么旧的内存位置删除后总是充满0xDDDDDDDD?是不是表示内存被释放的标志?如果它已经在假设的“可用内存列表”中跟踪它,为什么还要这样做呢?我的意思是写入内存需要一些努力(即使在这个例子中可以忽略不计),为什么不把它留在那里,直到有其他东西覆盖它。

虽然最初ptr指向某个随机地址,但是在删除操作之后,它始终指向0x0000000000008123。是不是也是一个标志,表明指针现在指向了一个不可访问的内存块?

(我在 Windows 10 64 位操作系统上使用 Visual Studio 2022)

仅仅一些好文章的链接也会有帮助。谢谢你。

c++ memory-management new-operator delete-operator
1个回答
0
投票

为什么旧的内存位置删除后总是填满0xDDDDDDDD?

您的平台的调试版本在内存释放后将

memset
设为 0xDD。

标准中没有规定。这是特定于您的平台的实施细节。

q.v. DDDDDDDD 值的

幻数

是不是内存被释放的标志?

不,这是一个帮助调试的标记。

如果它已经在假设的“可用内存列表”中跟踪它,为什么还要这样做呢?

帮助调试很麻烦。

我的意思是写入内存需要一些努力(即使在这个例子中可以忽略不计),为什么不把它留在那里直到有其他东西覆盖它。

它可以帮助调试。

© www.soinside.com 2019 - 2024. All rights reserved.