简体   繁体   中英

c programming: casting “void pointer” to point to struct

I'm writing this program to practice C programming, this is my code:

#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". 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. 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 . You're never changing that value.

Later, you read dmk->p . You're now in Undefined Behavior (UB) territory. The program could easily have faulted right there, because you were reading from a NULL pointer.

Apparently it didn't, though, because you're seeing your NULL ALERT message, and so we continue.

Then you do this:

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

On the second line there, cl is completely indeterminate. It could be garbage, it could be NULL , whatever, because you're entered UB territory. 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.

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).

So from here, it is speculation, as UB means anything can happen .

Apparently the printf passes, probably because the address can be read. The following write OTOH fails, generating the system messsage.

You don't initialize dmk in your code. That dmk->p is NULL is pure luck. Anything could happen.

You need to allocate memory for your struct using, for instance, malloc(), and initialize the members properly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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