我正在编写这个程序来练习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;
}
编译时,它没有显示任何错误或警告。但是当我运行该程序时,终端告诉我“核心转储”并没有显示任何结果接受“空警报”。谁能解释我失败的原因?非常感谢。
答案 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()为结构分配内存,并正确初始化成员。