【问题标题】:Free after assigning value for field in global structure为全局结构中的字段赋值后释放
【发布时间】:2016-12-08 10:31:21
【问题描述】:

这是我试图理解的小型 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-&gt;x 时,是否复制了引用而不是值?如何验证?

【问题讨论】:

  • xx.x 从未初始化。

标签: c scope free


【解决方案1】:

您的局部变量 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(&amp;xx,yy);

【讨论】:

  • 谢谢,我意识到在发布问题后我在 main 中有压倒一切的定义。由于我对结构的每个字段进行了一些完整性检查(结构有多个字段),因此我无法直接修复您的建议。分配 xx.x = yy-&gt;x 是否安全,如果有静态全局 xx 并且 set_user_params 是从另一个 c 文件调用的?
【解决方案2】:

问题与yyfree 调用无关。

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

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

【讨论】:

    【解决方案3】:
    dm_user_params xx;
    

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

    【讨论】:

      【解决方案4】:

      删除该行

      dm_user_params xx;
      

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

      【讨论】:

        【解决方案5】:

        试试这个:

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

        【讨论】:

          【解决方案6】:

          这里的问题是,main() 之外的全局xxmain() 中的内部xx 遮蔽。

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

          [...] 如果一个标识符指定两个不同的实体同名 空间,范围可能重叠。如果是这样,一个实体的范围(内部范围)将结束 严格在其他实体的范围之前(外部范围)。 在内部范围内, 标识符指定在内部范围内声明的实体;在外部声明的实体 范围在内部范围内隐藏(不可见)。

          所以,在你的情况下,

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

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

          解决方案:main()中删除xx的局部变量定义。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-05-03
            • 1970-01-01
            • 1970-01-01
            • 2019-09-10
            • 1970-01-01
            • 1970-01-01
            • 2019-10-30
            • 1970-01-01
            相关资源
            最近更新 更多