【问题标题】:How can I fix pointer problem in my C code?如何修复 C 代码中的指针问题?
【发布时间】:2020-04-25 14:28:35
【问题描述】:
#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;
}

在我的代码中,出现“分段错误”问题,但我不知道如何修复我的代码..

我只想修复 **(int **)arg = foo; 行。

有人可以帮帮我吗?

【问题讨论】:

    标签: c pointers segmentation-fault


    【解决方案1】:

    在您的代码中,函数test(void **temp),变量 temp 是指向指针的指针,也就是双指针。也就是说,它的值是一个地址。但是当你从 main 调用 test 时,那个值是 0,这意味着地址是地址 0。

    您不能为地址 0 赋值。

    【讨论】:

      【解决方案2】:

      看起来您正在向地址 0 写信。

      因为:

      &amp;temp 是一个指向 int 的指针。

      *((int**)&amp;temp) 是一个整数。

      **((int**)&amp;temp) 使用您在 temp 中的值作为地址。

      【讨论】:

        【解决方案3】:

        你的功能

        void test(void **arg);
        

        需要一个 “指向 void 的指针”,即包含另一个指向通用数据的地址的位置的地址。

        当你调用函数时,你没有传递它所期望的

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

        其实&amp;temp是一个指向整数的地址。但它需要一个地址的地址!因此,当在函数内部时,您在第二次尝试访问地址 0 时将其延迟两次(每次使用 * 运算符进行延迟都意味着“解析”一个地址)。

        为了修复它,只需将指向指针的指针传递给test

        int temp = 0;
        int *tempAddr = &temp; //tempAddr points to temp
        
        test((void **)&tempAddr); //The type of the address of tempAddr is 'int  **'
        

        您实际上是在问另一件事:您明确要求修复 **((int **) arg) = foo; 行。

        这并不容易,因为您当前收到了一个无效的指针指针,并且无法仅更改该行使其有效。为了解决这个问题,您需要更改test() 接口,如下所示:

        #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;
        }
        

        【讨论】:

        • 但是,pthread_join 函数可以做到。如何在 pthread_join 函数中完成?例如,int exitCode; pthread_join(tid, (void**)&exitCode); --> exitCode 将是整数!
        • 来自 pthread_join 指南:"如果 retval 不为 NULL,则 pthread_join() 复制目标线程的退出状态(即目标线程提供给 pthread_exit(3) 的值)进入 retval 指向的位置。”. retval 必须是 VALID 指针。
        猜你喜欢
        • 2020-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-13
        • 1970-01-01
        • 2021-06-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多