c ++中的内存是如何释放的

Jos*_*gal 1 c++ memory-management heap-memory

我完全理解内存的指针分配,但仅在更高级别上释放内存。我最好奇的是 C++ 如何跟踪哪些内存已经被释放?

int* ptr = new int;
cout << ptr;
delete ptr;
cout << ptr;
// still pointing to the same place however it knows you can't access it or delete it again
*ptr // BAD
delete ptr // BAD
Run Code Online (Sandbox Code Playgroud)

C++ 怎么知道我释放了那块内存。如果它只是将其转换为任意垃圾二进制数,那么当我取消引用指针时,我不会只是在读取该垃圾数吗?

相反,当然,c++ 知道这些是段错误。

fre*_*ish 5

C++不会为您跟踪内存。它不知道,它不在乎。这取决于你:程序员。(De)allocation 是对底层操作系统的请求。或者更准确地说,它是对 libc++(或可能是其他一些 lib)的调用,它可能会或可能不会访问操作系统,这是一个实现细节。无论哪种方式,操作系统(或其他一些库)都会跟踪您可以使用的内存部分。

当您尝试访问操作系统未分配给您的内存时,操作系统会发出段错误(从技术上讲,它是由 CPU 引发的,假设它支持内存保护,则有点复杂)。这是一个很好的情况。操作系统会通过这种方式告诉您:嘿,您的代码中存在错误。请注意,操作系统并不关心您是使用 C++、C、Rust 还是其他任何东西。从操作系统的角度来看,一切都是机器代码。

然而,更糟糕的是,即使delete内存可能仍归您的进程所有(还记得那些跟踪内存的库吗?)。所以访问这样的指针是一种未定义的行为,任何事情都可能发生,包括正确执行代码(这就是为什么通常很难找到这样的错误)。

如果它只是将其转换为任意垃圾二进制数,那么当我取消引用指针时,我不会只是在读取该垃圾数吗?

谁说变成垃圾了?底层内存真正发生了什么(操作系统是否回收它,或者它被零或一些垃圾填充,或者什么都没有)与您无关。您需要知道的一切是,在delete使用指针不再安全之后。甚至(或尤其)当它看起来不错时。


eer*_*ika 5

C++ 如何知道我释放了该内存。

当您使用delete表达式时,“C++ 知道”您已释放该内存。

如果它只是将其转换为任意垃圾二进制数

C++ 不会“将[已释放的内存] 转换为任意垃圾二进制数”。C++ 只是使内存可用于其他分配。更改该内存的状态可能是使用该内存的程序其他部分的副作用 - 现在可以自由地执行此操作。

当我取消引用指针时,我不会只是读取那个垃圾数字吗?

当您间接通过指针时,程序的行为是未定义的。

相反,当然,c++ 知道这些在某种程度上是段错误。

这就是你的操作系统介入的地方。你做了一些没有意义的事情,操作系统杀死了行为不当的进程。这是当程序的行为未定义时可能发生但也可能不会发生的众多事情之一。