c编程:将“void pointer”转换为指向struct

时间:2015-10-04 10:46:52

标签: c pointers

我正在编写这个程序来练习C编程,这是我的代码:

#include <stdio.h>
#include <stdlib.h>
struct s1 {
        int i;
        void * p;
    };
static struct s1 *dmk;
int main(void) {

    int tong(int a, int b);
    int (*tinh)(int,int);

    struct s2 {
        int num;
        int (*cal)(int a, int b);
    };
    if(dmk->p == NULL)
    {
        printf("NULL ALERT\n");
    }
    struct s2 *cl = dmk->p;
    cl->cal = tong;

    tinh = ((struct s2 *)(dmk->p))->cal;
    printf("tinh 2, 4 ra %d\n",tinh(2,4));
    puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
    return EXIT_SUCCESS;
}

int tong(int a, int b)
{
    return a + b;
}

编译时,它没有显示任何错误或警告。但是当我运行该程序时,终端告诉我“核心转储”并没有显示任何结果接受“空警报”。谁能解释我失败的原因?非常感谢。

4 个答案:

答案 0 :(得分:3)

if(dmk->p == NULL)

失败,因为dmk 未初始化初始化为NULL,指向“no-where”,因此取消引用它会调用未定义的行为。事后可能会发生任何事情。

答案 1 :(得分:2)

底线是你做错了就是在使用它们之前没有为你的各种指针分配东西。

您的dmk是全局的,因此其初始值为NULL。你永远不会改变这个价值。

稍后,您阅读dmk->p。您现在处于未定义行为(UB)区域。该程序可能很容易在那里出现故障,因为您正在从NULL指针读取。

显然它没有,因为你看到了NULL ALERT消息,所以我们继续。

然后你这样做:

struct s2 *cl = dmk->p;
cl->cal = tong;

在第二行,cl完全不确定。它可能是垃圾,它可能是NULL,无论如何,因为你进入了UB领域。然后你取消引用它并写入结果。你可能想在任何地方写作。写入随机指针(或NULL指针)往往会使核心转储和其他Bad Things™发生。

在使用指针之前,您需要实际为指针赋值。

答案 2 :(得分:2)

dmk是一个全局(又名。静态(这是static关键字相关!)变量,因此它被初始化为 null指针。您不会更改此值,因此dkms->p取消引用空指针,它会调用未定义的行为(UB)。

所以从这里开始,这是猜测,因为UB意味着任何事情都可能发生

显然printf通过,可能是因为可以读取地址。以下写OTOH失败,产生系统乱码。

答案 3 :(得分:1)

您没有在代码中初始化dmk。 dmk-&gt; p为NULL是纯粹的运气。任何事情都可能发生。

您需要使用例如malloc()为结构分配内存,并正确初始化成员。