我与这个问题斗争了 2 天。我有一个解决方法,但我想了解更多会发生什么。那么让我们开始吧。我有一个非常原始的异常类,它将错误消息作为指向字符数组的指针(我知道 std::string 的利润)。我知道“三法则”,所以它看起来像:
全局异常.hpp
class FatalError {
public:
const char* errorMessage;
/* WARNING:
* "Rule of three". You see it below.
*/
FatalError(const char* pErrorMessage);
FatalError(const FatalError& rhs);
FatalError& operator=(const FatalError& rhs);
~FatalError();
};
全局异常.cpp
FatalError::FatalError(const char *pErrorMessage):
errorMessage(pErrorMessage)
{}
FatalError::FatalError(const FatalError& rhs){
char* buf = new char[strlen(rhs.errorMessage)+1];
strcpy(buf, rhs.errorMessage);
errorMessage = buf;
}
FatalError& FatalError::operator =(const FatalError& rhs){
if (this == &rhs)
return *this;
delete[] errorMessage;
char* buf = new char[strlen(rhs.errorMessage)+1];
strcpy(buf,rhs.errorMessage);
errorMessage = buf;
return *this;
}
FatalError::~FatalError(){
delete[] errorMessage;
}
但投掷时:
int Config::readConfig(int argc_p, char *argv_p[])
{
if ( argc_p != 2 )
{
throw FatalError ("Sick usage. Try: <file.ini>\n");
}
我得到“SIGABRT”。
一些valgrind分析:
Invalid free() / delete / delete[] / realloc()
in FatalError::~FatalError() in globalexceptions.cpp:26
Address 0x413980 is not stack'd, malloc'd or (recently) free'd 1: operator delete[](void*) in /tmp/buildd/valgrind-3.7.0/coregrind/m_replacemalloc/vg_replace_malloc.c:490
2: FatalError::~FatalError() in <a href="file:///home/gumba/Projects/cpp/backup_helper/backup_helper-build-desktop-Qt_4_8_2_in_PATH__System__Debug/../backup_helper/globalexceptions.cpp:26" >globalexceptions.cpp:26</a>
3: /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17
4: main in <a href="file:///home/gumba/Projects/cpp/backup_helper/backup_helper-build-desktop-Qt_4_8_2_in_PATH__System__Debug/../backup_helper/main.cpp:35" >main.cpp:35</a>
我做了一些研究,发现了以下信息和建议:
- (OK:Catch by reference)“从技术上讲,即使你通过引用捕获异常,编译器仍然使用按值传递。这是因为catch永远不会将控制权返回给调用者,因此负责清理-向上”
- (OK:有复制构造函数)“抛出的对象必须有一个可公开访问的复制构造函数。编译器可以生成复制抛出的对象任意次数的代码,包括零次。但是,即使编译器从未实际复制抛出的对象,它必须确保异常类的复制构造函数存在并且可以访问”
根据 GDB,不调用复制构造函数。SIGABRT 发生在delete[] errorMessage上。我不明白为什么。errorMessage 似乎已正确初始化。
SIGABRT 的原因是什么?
谢谢!