1

我正在阅读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;
}

编辑:

我认为我不理解的部分内容是“尊重”的含义。所以如果你把它放在你的答案中,那就太棒了。

4

3 回答 3

13

崩溃是由空指针的取消引用引起的:

(*p) = 0; // <--- Crash

同样正如评论中所指出的,未使用的宏只是为了抑制大多数编译器会给出的“未使用参数”警告。

通常也可以通过简单地不指定变量名称来防止警告,如下所示:

int MOAISim::_crash ( lua_State* ) 
{
    int *p = NULL;
    (*p) = 0;

    return 0;
}

还值得牢记的是,上述并非保证崩溃。在其中一个 32 位控制台上,取消引用空指针实际上会导致数字“3”。这确实使 null 取消引用很难找到,但通常如果您在寄存器中看到一个 3,您可能会很好地猜测刚刚出了什么问题。

取消引用本质上是要求存储在给定指针上的值。如果指针无效(即指向进程不拥有的内存位置),则会导致崩溃。在 Windows 中,这称为访问冲突 (0xC0000005)。在 Linux 下,这是一个分段违规,SIGSEGV。

也可以看看

于 2012-12-05T12:45:46.843 回答
3

宏在代码中被替换,因此对于编译器,函数如下所示:

int MOAISim::_crash ( lua_State* L ) {
    (( void )L);

    int *p = NULL;
    (*p) = 0;

    return 0;
}

(( void )L)行评估L并丢弃结果。但是,崩溃不是来自该行,而是来自分配NULL(*p) = 0.

于 2012-12-05T12:47:20.107 回答
1
int *p = NULL;
(*p) = 0;

第二行是未定义的行为(取消引用 nullptr 指针)。使您的平台上的应用程序崩溃的事实只是未定义行为的一种形式(在我看来很好,因为您可以更快地发现错误)。

于 2012-12-05T13:11:46.237 回答