所以有问题的代码行是:
*((int*)(0))=1;
Run Code Online (Sandbox Code Playgroud)
因为我对C/C++的经验很少而且没有非常努力,所以我不明白这个简单的表达方式.这究竟是什么意思?
Luc*_*ore 28
它意味着崩溃程序,通常在调试期间很有用.
它将取消引用NULL指针并尝试为该内存分配一个值,理论上这只是未定义的行为,但会导致99%的系统出现访问冲突异常.
通常,它可以在以下情况下找到:
if ( !FileRead(importantFile) )
{
// this should never happen, critical exception
*((int*)(0))=1;
}
Run Code Online (Sandbox Code Playgroud)
And*_*rew 11
一点一点地分解.在左侧的外部括号内,您有:
(int*)(0)
Run Code Online (Sandbox Code Playgroud)
这是一个值为0的C样式转换为指向int的指针; 创建一个空指针,实际上.
让我们添加一个变量来捕获第一个表达式的结果:
int* x = (int*)(0);
Run Code Online (Sandbox Code Playgroud)
外部现在是:
*(x) = 1;
Run Code Online (Sandbox Code Playgroud)
这是取消引用指针x,并为结果int赋值1.
由于(在这种情况下)x是一个空指针,这将在取消引用时崩溃(严格来说,它将在取消引用后的赋值中崩溃 - 请参阅下面的注释).它通常用于强制崩溃或其他依赖于系统的未定义行为; 通常用于测试或调试目的.您不希望在生产代码中使用这样的行.
注意:有些架构通常在嵌入式系统中,其中零是有效的内存地址,上面的代码可能有合法的用途.但是,如果您正在使用这样的平台,那么您不太可能在问题中使用语法.
正如其他人所说,这是一种落入调试器的方法.大多数计算机将拒绝写入内存地址0
,而是会进入某种诊断模式.
但是,更好的选择是标准功能raise()
,来自<signal.h>
或<csignal>
.raise( SIGSEGV )
会产生相同的结果,你的榜样打算,甚至计算机上都允许写入地址零(这样的机器确实存在!),并用不确定的行为自由的解释编译器.该操作无法保证或要求崩溃.从编译器的角度来看,它可能什么也不做,只是从编译的程序中删除它并不是不正确的.
有关更具描述性的信号值,请参阅man signal
.什么意思可能是raise( SIGTRAP )
,或abort()
.后者相当于raise( SIGABRT )
我的系统,但我很懒,检查POSIX或C语言是否保证了等效性.
归档时间: |
|
查看次数: |
1925 次 |
最近记录: |