使用C+;无法捕获访问冲突异常+;捕获(…) 下面的代码中,我想根据C++异常捕获模型的描述使用C++ ccatch(…)来捕获异步异常和同步异常。
此外,我还将“异常处理模型”设置为使用C+;无法捕获访问冲突异常+;捕获(…) 下面的代码中,我想根据C++异常捕获模型的描述使用C++ ccatch(…)来捕获异步异常和同步异常。,c++,error-handling,try-catch,strcpy,C++,Error Handling,Try Catch,Strcpy,此外,我还将“异常处理模型”设置为Yes,其中包含SEH异常(/EHa)值 我分别使用以下状态测试代码: 当我在未分配的char*(char*c;)中复制字符串时,我可以在catch(…)部分捕获其异常。(但我知道这是一种未定义的行为!) 但是,当我在一个字符数组中复制一个字符串(字符串大于数组大小)时,我无法捕获任何异常 在第二种状态下,调试时,我得到了访问冲突错误。但是为什么不能像第一个州那样捕捉到它的异常呢 我尝试了另一种解决方案,如中所述: 但问题依然存在 这是我的代码(
Yes,其中包含SEH异常(/EHa)
值
我分别使用以下状态测试代码:
- 当我在未分配的
(char*
)中复制字符串时,我可以在char*c;
部分捕获其异常。(但我知道这是一种未定义的行为!)catch(…)
- 但是,当我在一个字符数组中复制一个字符串(字符串大于数组大小)时,我无法捕获任何异常
- 在第二种状态下,调试时,我得到了访问冲突错误。但是为什么不能像第一个州那样捕捉到它的异常呢
- 我尝试了另一种解决方案,如中所述:
这是我的代码(我在未分配的
char*
和字符数组上测试了strcpy()
):
intmain()
{
char c[3]={0};//无法捕获任何异常
//char*c;//可以捕获异常
尝试
{
strcpy(c,“abcdefghijklmnopqrstuvxyz1234567890”);
}
捕获(…)
{
cout访问冲突不需要引发异常
你这里有未定义的行为。根据
如果dest数组不够大,则行为未定义。如果字符串重叠,则行为未定义
它们都是未定义的行为,并且未定义的行为没有任何可信赖的行为。因此,您不能指望您的try
/catch
捕获UB引起的异常,因为可能没有任何异常。方法就是不要有任何未定义的行为。异常会发生在预先声明的东西上下功夫。这里发生的是UB,那里没有诊断要求。还有“金属”从外观上看,只要进程允许写入的内存发生写入,超出数组边界就不一定会导致访问冲突。@Swift FridayPie当我对未分配的字符*使用strcpy时,为什么会出现异常?在第二种状态下,我得不到任何异常?第二种情况:您有一个未初始化的指针,它将e被strcpy
取消引用,即UB。实际上指针的值是不确定的,一些随机值从未由新表达式或malloc()返回
。使用该值作为地址进行写入会导致进程访问未分配给进程或不可写的内存。因此会导致分段错误或类似状态。对于程序而言,第一种情况比第二种情况更危险,因为程序无法继续运行。但不总是这样:在大系统中,随机值pointer实际上可能是以前的值之一,并且指向内存的某个已使用区域。在那里写入会导致数据或程序流的灾难性损坏。第一种情况可能会导致模糊的安全风险。例如,有两个缓冲区,超过一个缓冲区,您将写入第二个缓冲区,结果,您可能会发送不打算使用的数据nd.最近ssh的心跳缺陷就是这种UBs。当然,但这并不是真正的问题。他们说他们遇到了访问冲突,而且没有被发现。最有可能强制内存保护故障的简单修改是strcpy(NULL,“die”)
@paddy:访问冲突会导致异常吗?我不这么认为。如果会,它会被捕获。实现不需要为访问冲突引发异常。这就是这个答案所说的。不,它不会。答案只是搅乱了那些水域,因为你在路过时提到它,会以一种用你的语言将它压垮的方式strcpy
文档的摘要,而不是一个与strcpy
或未定义行为完全无关的单独事实。@paddy为什么我可以在对未分配的char*
使用strcpy
时获得异常?在第二种状态下,我无法获得任何异常?@paddy。大多数实现都无法捕捉到这一点。在POSI上X系统您可以通过使用信号的运行时处理程序捕获一些信号,因为操作系统应该向进程发送特定的信号,但在这种情况下,该信号不可接受并导致进程关闭。在内部的任何其他逻辑可能阻止它之前。这是一个明智的设计,因为否则错误的进程可能会对多用户环境造成损害甚至使操作系统不可操作(足以达到能够写入映射到内存的文件的状态)。
int main()
{
char c[3] = { 0 }; // Cannot catch any exception
//char *c; // Can catch exception
try
{
strcpy(c, "abcdefghijklmnopqrstuvwxyz1234567890");
}
catch (...)
{
cout << "Undefined behavior!" << endl;
}
return 0;
}