简体   繁体   English

c编程:强制转换“ void指针”以指向结构

[英]c programming: casting “void pointer” to point to struct

I'm writing this program to practice C programming, this is my code: 我正在编写此程序来练习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;
}

When I compiled it, it didn't show any error or warning. 当我编译它时,它没有显示任何错误或警告。 But when I ran the program, the terminal told me that "core dumped" and did not show any result accept for the "NULL ALERT". 但是,当我运行该程序时,终端告诉我“ core dumped”并且没有显示接受“ NULL ALERT”的任何结果。 Can anyone explain why I failed ? 谁能解释我为什么失败? Thanks alot. 非常感谢。

if(dmk->p == NULL)

fails as dmk is uninitialised initialised to NULL , points "no-where", so de-referencing it invokes undefined behaviour. 失败,因为dmk 初始化为NULL ,指向“ no-where”,因此取消引用它会调用未定义的行为。 Anything can happen afterwards. 之后什么都可能发生。

Bottom line is that what you're doing wrong is not assigning things to your various pointers before using them. 最重要的是,您在做错的事情是在使用指针之前没有将它们分配给各种指针。

Your dmk is a global, so its initial value is NULL . 您的dmk是全局的,因此其初始值为NULL You're never changing that value. 您永远都不会改变这个价值。

Later, you read dmk->p . 稍后,您阅读dmk->p You're now in Undefined Behavior (UB) territory. 您现在处于未定义行为(UB)区域。 The program could easily have faulted right there, because you were reading from a NULL pointer. 该程序很容易在此处出错,因为您正在从NULL指针中读取。

Apparently it didn't, though, because you're seeing your NULL ALERT message, and so we continue. 显然没有,因为您看到的是NULL ALERT消息,因此我们继续。

Then you do this: 然后您执行以下操作:

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

On the second line there, cl is completely indeterminate. 在第二行, cl完全不确定。 It could be garbage, it could be NULL , whatever, because you're entered UB territory. 可能是垃圾,可能是NULL ,因为您已进入UB区域。 Then you dereference it and write to the result . 然后您取消引用它并写入结果 You could be trying to write anywhere. 您可能想在任何地方写。 Writing to random pointers (or NULL pointers) tends to make core dumps and other Bad Things™ happen. 写入随机指针(或NULL指针)往往会使核心转储和其他Bad Things™发生。

You need to actually assign values to your pointers before you use them. 在使用指针之前,您实际上需要为其分配值。

dmk is a global (aka. static (this is not related to the static keyword!), variable, thus it is initialized to a null pointer . You do not change this value, so dkms->p dereferences a null pointer , which invokes undefined behaviour (UB). dmk是一个全球性的(亦称静态的(这是相关的static关键字!),可变的,因此它被初始化为空指针 。你不改变这个值,所以dkms->p解引用一个空指针 ,它调用未定义行为 (UB)。

So from here, it is speculation, as UB means anything can happen . 所以从这里开始,这就是猜测,因为UB意味着任何事情都可能发生

Apparently the printf passes, probably because the address can be read. 显然printf通过了,可能是因为可以读取地址。 The following write OTOH fails, generating the system messsage. 以下写入OTOH失败,生成系统消息。

You don't initialize dmk in your code. 您无需在代码中初始化dmk。 That dmk->p is NULL is pure luck. dmk-> p为NULL纯属幸运。 Anything could happen. 什么事情都可能发生。

You need to allocate memory for your struct using, for instance, malloc(), and initialize the members properly. 您需要使用例如malloc()为结构分配内存,并正确初始化成员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM