未更新结构指针的值

Value of structure pointer not being updated

我正在尝试实现一个函数,它接受两个指向结构 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->item); 进行注释,程序将正常运行并且我得到输出“End”。为什么会这样?

编辑

如果我有一个集合并将其传递给 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;
}

提前致谢。

您应该按照您的目的使用传递结构的地址,如下所示。

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

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

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

看下面这行:

 data1 = tmp;

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

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

通过将函数签名更改为:

void changeVal(data **data1)

假设您调用:

data *d;
changeVal(&d);

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

*data1 = malloc...

这与在 main 中使用 d 相同:

d = malloc...