为全局结构中的字段赋值后释放

Free after assigning value for field in global structure

这是我试图理解的小 C 程序:

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

typedef struct dm_user_params_t {
    int x;
} dm_user_params;

dm_user_params xx;

void set_user_params(dm_user_params *yy) {
    xx.x = yy->x;
}

int main() {
    dm_user_params xx;
    dm_user_params *yy;
    yy = malloc(sizeof(dm_user_params));
    yy->x = 217;
    set_user_params(yy);
    free(yy);
    printf("2 %d" , xx.x);
    return 0;
}

输出:

537340672

我应该怎么做才能使 xx.x 中的值保持不变?

当我执行 xx.x = yy->x 时,是否复制了引用而不是值?如何验证?

此问题与 yyfree 调用无关。

而是因为您有 两个 个名为 xx 的自变量。一个是 set_user_params 函数将使用的全局变量。另一个是 local 变量,printf 函数将使用该变量。局部变量还没有被初始化,所以它的值将是indeterminate.

解决方案是或者删除局部变量。 删除全局变量并将指向局部变量的指针作为额外参数传递给set_user_params函数。

您的局部变量 xx 正在隐藏全局相同的声明(带有确切的类型和名称)

set_user_params 更改全局 xx

修复 1:删除局部变量。另外:

void set_user_params(dm_user_params *yy) {
    xx.x = yy->x;
}

可以写成:

void set_user_params(const dm_user_params *yy) {
    xx = *yy;
}

因此,当您添加更多字段时,set_user_params 不需要更新。

修复 2:删除全局变量并按原样更改原型:

void set_user_params(dm_user_params *dest, const dm_user_params *src) {
    *dest= *src;
}

然后这样调用set_user_params(&xx,yy);

这里的问题是,main() 外部的全局 xxmain() 中的内部 xx 覆盖。

引用 C11,章节 §6.2.1,标识符的范围,(强调我的

[...] If an identifier designates two different entities in the same name space, the scopes might overlap. If so, the scope of one entity (the inner scope) will end strictly before the scope of the other entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.

所以,在你的情况下,

 printf("2 %d" , xx.x);

正在尝试访问未初始化的局部变量 xx.x,调用 undefined behavior.

解决方法:main().

中删除xx的局部变量定义
dm_user_params xx;

main() 中,局部变量 xx 未初始化,而全局变量 xx 已初始化。您正在打印未初始化的值。

删除行

dm_user_params xx;

在你的 main 中,它会起作用。 您有两个变量 xx,一个是局部变量,一个是全局变量。您将函数 set_user_params 中的全局变量设置为 217,但稍后在您的 main 中打印本地变量,该变量未初始化并将导致未定义的行为。

试试这个:

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

typedef struct 
{
    int x;
} dm_user_params_t;

dm_user_params_t xx;

void set_user_params(dm_user_params_t *yy) 
{
    xx.x = yy->x;
    printf("Got : %d \n",yy->x);
}

int main(void) 
{
    // dm_user_params_t xx; Note: Local object getting highest priority than global, that's why you are getting garbage value
    dm_user_params_t *yy;
    yy = malloc(sizeof(dm_user_params_t));
    yy->x = 217;
    set_user_params(yy);
    free(yy);
    printf("2 %d" , xx.x);
    return 0;
}