简体   繁体   中英

In C, using a pointer to a struct to call a function pointed to inside the struct leads to seg fault

I have no experience with function pointers, but I think it's something I should know, so I dove in with a simple program. I've increasingly been working in the kernel object domain, where structs and function pointers are fairly common.

This causes a seg fault:

int nada(int input){
    printf("value = %d", input);
}

typedef struct foo{
    void (*funcptr)(int);
}foo;

main()
{
    foo* FOO;
    FOO->funcptr = nada;

    FOO->funcptr(5);
}

But having a main like this instead:

main()
{
    foo FOO;
    FOO.funcptr = nada;

    FOO.funcptr(5);
}

does not cause a seg fault.

Also, I get a warning for the assignment of the function pointer:

main.c:16:17: warning: assignment from incompatible pointer type [enabled by default] FOO.funcptr = nada;

Does anyone have an explanation?

When you have

foo* FOO;
FOO->funcptr = nada;

FOO is pointer and you should allocate memory to it before accessing it. Without that you are accessing random memory which may produce crash.

So update code to

foo* FOO = malloc(sizeof(*FOO));
FOO->funcptr = nada;

And free the memory once used.


For the warning

main.c:16:17: warning: assignment from incompatible pointer type [enabled by default] FOO.funcptr = nada;

You have defined nada as function returning int . But your pointer to function does not return anything (has void return type) which is mismatch hence the warning.

In your original line, this:

foo* FOO;

Doesn't create a foo , it creates a pointer to a foo that doesn't currently point to anything. You then attempt to access the non-existant foo :

FOO->funcptr = nada;

causing a segfalt, since that pointer doesn't point anywhere (this is technically undefined, it could do anything, but will usually segfault).

In your other example, this:

foo FOO;

actually creates a foo instance, so accessing/assigning its members is legal. You need to use foo* FOO = malloc(sizeof(foo)) to create a new foo that is assigned directly a pointer (remember to free!), or assign the pointer to an existing foo instance.

try this..without using malloc()

#include <stdio.h>

int nada(int input){
    printf("value = %d", input);
}

typedef struct foo{
    int (*funcptr)(int input);
} foo;

main()
{
    foo Foo;
    Foo.funcptr = nada;
    Foo.funcptr(5);
}

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