0
typedef void(*FUNC)(void);
int main(void)
{
        //intptr_t m;
    const static unsigned char insn[4] = { 0xff, 0xff, 0xff, 0xff };
        FUNC function = (FUNC) insn;
        function();
}

上面的代码给了我一个非法指令的输出。有人可以解释为什么吗?. 是不是因为函数指针没有函数的地址(因为它有一个数组的地址,所以它不能跳转到该地址)

4

2 回答 2

1

由于指向数组第一个元素的指针不是指向函数的指针,因此您可以通过变量调用“函数”来调用未定义的行为function。当您调用未定义的行为时,任何事情都可能发生。带有非法指令的崩溃是完全合法的;擦除磁盘上的所有数据也是如此。

根据标准,没有什么可以“预期”。正如评论中所暗示的那样,可能发生的情况是存储在数组中的堆栈中的字节insn(以及堆栈的其余部分,以及堆栈帧main()以及参数列表和环境变量等内容)将被处理作为机器码。幸运的是,其中一个字节是无效(或非法)指令,程序停止。

于 2013-09-11T03:12:18.540 回答
0

C11 J.5.7 函数指针转换

1 指向对象或 tovoid的指针可以转换为指向函数的指针,从而允许将数据作为函数调用 (6.5.4)。

2 指向函数的指针可以转换为指向对象或指向的指针void,从而允许检查或修改函数(例如,通过调试器)(6.5.4)。

如果您只将数组名称转换为函数指针,那您很好,但是您调用它是未定义的行为,因为它实际上不是一个函数。

您可以尝试将实际的函数指针地址存储在数组中,然后将其转换回函数指针并调用它们。但是,unsigned char仍然无法使用,因为它太小了,请uintptr_t改用。

于 2013-09-11T03:28:30.840 回答