【问题标题】:Why does this very simple and little C++ program terminates with -1073741819 (0xC0000005)?为什么这个非常简单的小 C++ 程序以 -1073741819 (0xC0000005) 结束?
【发布时间】:2021-02-20 07:00:06
【问题描述】:

我有一个带有析构函数的简单类。如果我使用默认构造函数从中实例化一个对象,则程序会成功终止,但如果我使用具有任何参数的构造函数对其进行实例化,则程序会失败。

#include <iostream>
#include <list>

class MyClass {
public:
    std::list<int>* myList;
    MyClass();
    MyClass(int a);
    ~MyClass();
};

MyClass::MyClass() {}
MyClass::MyClass(int a) {}
MyClass::~MyClass() { delete myList; }

int main()
{

    // If I do only this, the program terminates succesfully with 0 as return value
    MyClass graph1();

    // But if I do this, the program terminates unsuccesfully
    MyClass graph2(3);

    return 0;
}

【问题讨论】:

  • 为什么myList 是一个指向 std::list 的指针?这是不寻常的,也是您的问题的原因。
  • delete myList - 但你从来没有new它!
  • 如果你想使用myList 作为指针,你的类还必须遵循 3 或 5 的规则,这比 0 的规则更有效。https://en.cppreference.com/w/cpp/language/rule_of_three
  • 从 C++11 开始,不要明确使用 newdelete。利用 RAII 模式并使用 std::unique_ptrstd::shared_ptr。还有一个指向srd::list&lt;int&gt; 的指针有点矫枉过正。
  • 这是 UB(deleteing 指针,你永远不会 new),代码可以做任何事情,但我对这种特定行为感到惊讶。

标签: c++ destructor terminate


【解决方案1】:

MyClass graph1(); 不会创建MyClass 的实例,无论是否使用默认构造函数初始化。相反,它是一个不带参数并返回MyClass 的函数的声明。另见:most vexing parse

MyClass graph2(3); 确实创建了MyClass 的实例。它的构造函数使myList 指针未初始化,然后其析构函数通过访问所述未初始化的指针表现出未定义的行为。

【讨论】:

  • 啊哈,说得有道理。最令人头疼的解析被恰当地命名。
  • @DanielH — 适当命名,但未适当调用。这不是最令人烦恼的解析示例。它只是一个函数声明。
猜你喜欢
  • 1970-01-01
  • 2015-10-18
  • 1970-01-01
  • 2016-12-22
  • 1970-01-01
  • 1970-01-01
  • 2020-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多