我有一个第三方库,有时会抛出异常.所以我决定将我的代码包装在try/catch(...)中,以便我可以记录有关发生异常的信息(没有具体的细节,只是它发生了.)
但由于某种原因,代码仍然崩溃.在客户端计算机上,它很难崩溃,并且在catch(...)中记录异常的代码永远不会被执行.如果我在我的调试/开发机器上运行它,我会看到弹出窗口询问我是否要调试.当我这样做时,它报告0xC0000005:访问冲突读取位置XXX.
奇怪的是,对于旧版本的第三方库,完全相同的代码可以捕获异常,并且记录异常的代码可以执行.(我在VS中验证了这一点,看着出现同样的情况.)
这是正在执行的伪代码:
pObject = pSystem->Get_pObject()
pSystem->DoSomethingThatMightDestroy_pObject();
try
{
/* Call to third party function that is throwing exception */
pObject->SetValue(0);
}
catch (...)
{
__DEBUG_LOG_POSITION__; // A macro to log the current file line
// This code used to run in the older version of third-party library
// but the newer version just crashes before running the catch(...)
}
Run Code Online (Sandbox Code Playgroud)
所以我有两个问题:
第三方编译库的方式是否有一些变化,以至于我的代码无法捕获异常?(是的,如果我知道要告诉他们什么,我有可能让第三方做出必要的修改并为我重新编译.)
假设我无法让第三方修复它,我该怎么做才能捕获这些异常?我正在考虑......是否有某种方法可以确定pObject是否已被释放?
考虑这个程序:
int main()
{
struct test
{
test() { cout << "Hello\n"; }
~test() { cout << "Goodbye\n"; }
void Speak() { cout << "I say!\n"; }
};
test* MyTest = new test;
delete MyTest;
MyTest->Speak();
system("pause");
}
Run Code Online (Sandbox Code Playgroud)
我原本以为发生了崩溃,但发生了这种情况:
你好
再见,
我说!
我猜这是因为当内存被标记为已解除分配时,它不会被物理擦除,并且由于代码直接引用它,因此仍然可以在那里找到对象,完全完好无损.在调用之前进行的分配Speak()越多,崩溃的可能性就越大.
无论是什么原因,这对我的实际线程代码来说都是一个问题.鉴于上述情况,我如何可靠地判断另一个线程是否删除了当前想要访问的对象?
我正在创建一个具有初始化构造函数的类,const char*应该使用缓冲区中提供的应该包含字符串的数据安全地构造对象.我担心的是,用户可以使用带有错误数据的构造函数,例如NULL指向未分配内存的指针或指针等等.关键是,在这种情况下,我想完成创建对象(它将处于未定义但正确的状态),而不会导致段错误,例如,如果用户向我发送了指向我不应该读取的数据的指针.我想将所有输入验证发送到std::string构造函数,因此构造函数看起来像这样:
Foo(const char *s) : Foo(std::string(s)) {}
Run Code Online (Sandbox Code Playgroud)
但我的老师称这是一个"错误的想法".那么,处理这种情况的正确方法是什么呢?
还有一件事,我不能在这种情况下使用例外(这是我课程作业的一部分,当然还没有教过它).