首先:我知道如果一个对象的析构函数抛出应用程序的行为不能指望......问题是关于内存问题。
所以,现在很清楚了:
查看应用:
#include <stdlib.h>
#include <iostream>
class T
{
public:
T() : ma(0)
{std::cout << "T::T ->default<-" << std::endl; }
T(const char* a) : ma(a)
{std::cout << "T::T ->" << ma << "<-" << std::endl; }
~T()
{std::cout << "T::~T ->" << ma << "<-" << std::endl; }
private:
const char* ma;
};
int main()
{
T* t = new T();
delete t;
}
并查看它的 valgrind 输出:
$ valgrind ./a.out
==29554== Memcheck, a memory error detector
==29554== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==29554== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==29554== Command: ./a.out
==29554==
T::T ->default<-
T::~T ->==29554==
==29554== HEAP SUMMARY:
==29554== in use at exit: 0 bytes in 0 blocks
==29554== total heap usage: 1 allocs, 1 frees, 4 bytes allocated
==29554==
==29554== All heap blocks were freed -- no leaks are possible
==29554==
==29554== For counts of detected and suppressed errors, rerun with: -v
==29554== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
解释:T::~T ->==29554==
告诉我析构函数遇到了危险情况(std::cout 接受了一个未定义的空值)所以应用程序的行为是无法控制的......
因为它没有打印出 "<-"
它立即给了我 valgrind 提示,我希望它在那个特定点退出。 Valgrind 不报告任何段错误或类似的东西......
而且,valgrind 报告没有内存泄漏......这让我感到困惑......所以我认为发生的事情是:
- 我调用
delete t;
- 应用程序释放内存
t
-
t
的析构函数被称为。
你能解释一下这里发生了什么吗?
编辑:要有一个更明确的问题:
当 std::cout 获取空对象时,是否在释放的内存上调用析构函数或析构函数中没有未定义的行为?
最佳答案
未定义的行为是未定义的。
如果非要我猜的话,在这种情况下,流会检测到空指针并进入错误状态,因此您根本看不到任何更多输出。删除过程的其余部分显然按预期继续进行。
其他形式的未定义行为,例如实际取消引用空指针,可能会产生不同的结果。同样,当您违反其要求时,其他流实现的行为可能会有所不同。
关于C++ 析构函数和内存分配,以及未定义的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22407711/