【问题标题】:Value of structure pointer not being updated结构指针的值未更新
【发布时间】:2021-03-13 18:15:22
【问题描述】:

我正在尝试实现一个函数,该函数接受两个指向结构 data1data2 的指针并更新它们的值。

这是我尝试过的,但我得到了Segmentation fault

#include <stdio.h>
#include <stdlib.h>

struct data{
    int item;
    int count;
};
typedef struct data data;

void changeVal(data *data1, data *data2, int value)
{
    data *tmp = malloc(sizeof * tmp);

    tmp->item = value;
    tmp->count = 10;

    data1 = tmp;
    data2 = tmp;
}

int main()
{
    data *data1 = NULL;
    data *data2 = NULL;
    
    changeVal(data1, data2, 39);
    printf("%d\n", data1->item);
    
    printf("End");

    return 0;
}

但是,如果我注释 printf("%d\n", data1-&gt;item); 行,程序运行正常,我得到输出“结束”。为什么会这样?

编辑

如果我有一个集合并将其传递给changeVal 函数,则值会更新。这里发生了什么?

#include <stdio.h>
#include <stdlib.h>

struct data{
    int item;
    int count;
};
typedef struct data data;

struct collection{
    data *one;
    data *two;
};
typedef struct collection collection;

void changeVal(collection *cltn, int value)
{
    data *tmp = malloc(sizeof * tmp);
    tmp->item = value;
    tmp->count = 10;
    cltn->one = tmp;
    cltn->two = tmp;
}

int main()
{
    collection *cltn;
    cltn = malloc(sizeof(cltn));
    
    cltn->one = NULL;
    cltn->two = NULL;
    
    changeVal(cltn, 39);
    printf("%d\n", cltn->one->item);
    
    printf("End");

    return 0;
}

提前致谢。

【问题讨论】:

  • 函数应该是data**,更新应该是*data1 = tmp;。现在你正在更新一个按值传递的变量。
  • @EugeneSh。但为什么?这不是指向结构的指针吗?由于我是初学者,请您解释一下背后的原因。
  • 指针是变量,就像其他任何东西一样。为了让你的函数更新某些东西,它需要更新 pointee。也就是说,取一个按值传递的地址,去那个地址,更新那个地址的值。
  • @EugeneSh。为什么在第二种情况下箭头运算符cltn-&gt;one = temp会发生这种情况? (考虑对我的问题进行编辑)。
  • 因为您传递了一个指针 cltn 并更新它指向的内容,而不是指针本身。

标签: c pointers struct memory-management malloc


【解决方案1】:

在 C 中没有引用。有一种不同的类型将地址作为其值。

data1 包含您作为参数传递的任何内容的副本。由于您传递了一个地址,它将拥有该地址的副本,当您使用运算符 * 更改存储在那里的地址时,更改将反映在您调用的参数中。

看下面一行:

 data1 = tmp;

您正在更改存储在 data1 中的地址,该地址将不再与传递的参数相同。函数完成后,data1 不再存在,参数将具有相同的地址。

当您在参数中添加第二个 * 时,通过在函数内使用 * 您可以更改传递给它的变量的地址:

通过将函数签名更改为:

void changeVal(data **data1)

假设你打电话:

data *d;
changeVal(&d);

如果您使用 * 运算符访问函数内部:

*data1 = malloc...

这就像你在 main 中使用 d 一样:

d = malloc...

【讨论】:

    【解决方案2】:

    您应该使用传递结构的地址来达到您的目的,如下所示。

    #include <stdio.h>
    #include <stdlib.h>
    
    struct data{
        int item;
        int count;
    };
    typedef struct data data;
    
    void changeVal(data **data1, data **data2, int value)
    {
        data *tmp = malloc(sizeof (tmp));
        //make sure to check whether proper memory is allocated
        if(tmp)
        {
            printf("allocated mem for tmp is %u\n", tmp);
            tmp->item = value;
            tmp->count = 10;
            *data1 = tmp;
            *data2 = tmp;
        }
        else
        {
            printf("malloc failed\n");
        }
    }
    
    int main()
    {
        data *data1 = NULL;
        data *data2 = NULL;
    
        printf("before memory allocation data1 is %u\n", data1);    
    
        changeVal(&data1, &data2, 39);
        printf("%d\n", data1->item);
    
        printf("after allocated memory data1 is %u\n", data1);
    
        // free the allocated memory
        free(data1);
            data1 = NULL;
            data2 = NULL;
    
        printf("End");
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-21
      • 1970-01-01
      • 2020-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-13
      • 1970-01-01
      相关资源
      最近更新 更多