我正在阅读Moai源代码,我很好奇为什么会导致崩溃(或不...)
我真的不明白那个片段。
在档案A:
#define UNUSED(p) (( void )p)
在档案B中:
//----------------------------------------------------------------//
/** @name crash
@text Crashes Moai with a null pointer dereference.
@out nil
*/
int MOAISim::_crash ( lua_State* L ) {
UNUSED(L);
int *p = NULL;
(*p) = 0;
return 0;
}
编辑:
我认为我不理解的部分是" deference"手段。所以,如果你把它放在你的答案中那就太棒了。
答案 0 :(得分:12)
崩溃是由空指针的取消引用引起的:
(*p) = 0; // <--- Crash
同样如评论中所指出的,UNUSED宏仅用于抑制大多数编译器将提供的“未使用参数”警告。
通常也可以通过简单地不按如下方式指定变量名来阻止警告:
int MOAISim::_crash ( lua_State* )
{
int *p = NULL;
(*p) = 0;
return 0;
}
同样值得注意的是,上述情况并非有保障。在其中一个32位控制台上,取消引用空指针实际上导致数字“3”。这确实很难找到空的解引用,但一般来说,如果你看到一个3坐在一个寄存器中,你可能会错误地猜测出了什么问题。
取消引用实质上是要求存储在给定指针处的值。如果指针无效(即指向进程不拥有的内存位置),则会导致崩溃。在Windows中,这称为访问冲突(0xC0000005)。在Linux下,它是一个分段违规,SIGSEGV。
答案 1 :(得分:3)
宏在代码中被替换,因此对于编译器,函数如下所示:
int MOAISim::_crash ( lua_State* L ) {
(( void )L);
int *p = NULL;
(*p) = 0;
return 0;
}
(( void )L)
行评估L
并丢弃结果。但是,崩溃不是来自该行,而是来自NULL
的{{1}}地址的分配。
答案 2 :(得分:1)
int *p = NULL;
(*p) = 0;
第二行是未定义的行为(取消引用nullptr指针)。在您的平台上崩溃应用程序的事实只是一种未定义的行为(在我看来很好,因为你可以更快地捕获bug)。