在用户定义的异常的析构函数中释放动态内存

Freeing dynamic memory in user defined exeption's destructor

我正在尝试删除在用户定义异常的构造函数中分配的用户定义异常的析构函数中的动态内存。但是我得到核心转储说明内存被释放了两次:

user1@ubuntu:~/practice$ ./a.out
Test Exception
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000000f0b0b0 ***
Aborted (core dumped)

我怀疑 MyException 对象两次超出范围,一次在 myfunc() 中,另一次在导致此问题的 main 的 catch 块中。但是在这种情况下我不知道如何释放内存。你能帮帮我吗?

代码如下:

#include<iostream>
#include<exception>
#include<cstring>
using namespace std;

class MyException: public exception
{
    char *msg;
    public:
    MyException(){}
    MyException(char *str)
    {
        msg = new char[strlen(str)+1];
        strcpy(msg,str);
    }
    char *what()
    {
        return msg;
    }
    ~MyException() throw()
    {
        delete msg;
    }
};

class A
{
    public:
    void myfunc() throw(MyException)
    {
        throw MyException((char*)"Test Exception");
    }
};

int main()
{
    try
    {
        A ob;
        ob.myfunc();
    }
    catch (MyException e)
    {
        cout<<e.what()<<endl;
    }
}

问题已按照三原则解决。什么是三法则?

来自another SO answer

If you need to explicitly declare either the destructor, copy constructor or copy assignment operator yourself, you probably need to explicitly declare all three of them.

可以在 another SO questionWikipedia.

#include <iostream>
#include <exception>
#include <cstring>

using namespace std;

class MyException: public exception
{
    char *msg;
    public:
    MyException(const char *str)  // Making the constructor take a `const char*`
                                  // so it can be invoked with a string
                                  // literal
    {
        msg = new char[strlen(str)+1];
        strcpy(msg,str);
    }
    MyException(MyException const& copy)
    {
        msg = new char[strlen(copy.msg)+1];
        strcpy(msg,copy.msg);
    }
    char const* what() const // Making the return type 'const char*' and
                             // making the member function a const. That's
                             // necessary to make it an override of
                             // std::exception::what()
    {
        return msg;
    }
    ~MyException() throw()
    {
        delete msg;
    }
    MyException& operator=(MyException const& rhs)
    {
       if ( this != &rhs )
       {
          delete [] msg;
          msg = new char[strlen(rhs.msg)+1];
          strcpy(msg,rhs.msg);
       }
       return *this;
    }
};

class A
{
    public:
    void myfunc() throw(MyException)
    {
        throw MyException((char*)"Test Exception");
    }
};

int main()
{
    try
    {
        A ob;
        ob.myfunc();
    }
    catch (MyException e)
    {
        cout<<e.what()<<endl;
    }
}

输出:

Test Exception