简体   繁体   中英

How can I fix pointer problem in my C code?

#include <stdio.h>
void test(void **arg) {
    int foo = 3;
    **(int **)arg = foo; // I want to just fix this line!!
}

int main(void) {
    int temp = 0;
    printf("%d\n", temp);

    test((void **)&temp);

    printf("%d\n", temp);

    return 0;
}

In my code, It has problem 'Segmentation fault', but I don't know how can I fix my code..

I wanna fix just **(int **)arg = foo; line.

Can Anybody Help Me?

In your code, function test(void **temp) , variable temp is a pointer to a pointer, aka double pointer. That is to say, it value is an address. But when you call test from main, that value is 0, which means that address is address 0.

You can not assign a value to address 0.

It looks like you are writing to address 0.

Because:

&temp is a pointer to int.

*((int**)&temp) is an int.

**((int**)&temp) use your value from temp as address.

Your function

void test(void **arg);

expects a "pointer to pointer to void" , that is the address of a location that contains another address pointing to a generic data.

When you call the function you are not passing what it expects

int temp = 0;
test((void **)&temp);

In fact &temp is an address pointing to an integer. But it expects the address of an address, So, when inside the function you deference it twice (every deferencing with the * operators means "resolving" one address) the second time you are trying to access the address 0.

In order to fix it, just pass to test a pointer to pointer:

int temp = 0;
int *tempAddr = &temp; //tempAddr points to temp

test((void **)&tempAddr); //The type of the address of tempAddr is 'int  **'

You were actually asking a different thing: you explicitly asked for a fix of the **((int **) arg) = foo; line.

That's not so easy, as you are currently receiving an invalid pointer to pointer, and there's no way to make it valid just changing that line. In order to sort it out you would need to change test() interface, like shown below:

#include <stdio.h>
void test(void *arg) { // changed 'void **' to 'void *'
    int foo = 3;
    *(int *)arg = foo; // only one level of dereferencing
}

int main(void) {
    int temp = 0;
    printf("%d\n", temp);

    test((void *)&temp); // cast to 'void *' instead of 'void **'

    printf("%d\n", temp);

    return 0;
}

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