【问题标题】:Why does my C code print out different values when referring to the same variable?为什么我的 C 代码在引用同一个变量时会打印出不同的值?
【发布时间】:2021-04-16 20:29:28
【问题描述】:

这是我第一次尝试关于 stackoverflow 的问题 -

我在 C 中实现了以下内容:

在运行我的程序时,我发现打印出来的hashstring的值在以下两个函数中是不同的:

void foo() {
    ...
    Obj *obj = Obj(args);
    char *hashstring = getHash(obj);
    printf("My value of hashstring: %s\n", hashstring);
    ...
}

char* getHash(Obj *obj) {
    ...
    int hashint = getHashInt(args);
    // I am trying to do a conversion from int to string here
    char hashstring[12]; 
    sprintf(hashstring, "%d", hashint);
    printf("My value of hashstring: %s\n", &hashstring);
    return &hashstring;
}

打印出来的内容如下:
我的 hashstring 值:1001 // 在 getHash 中打印:这是预期的
我的哈希字符串值:0
我的 hashstring 值:2002 // 在 getHash 中打印:这是预期的
我的哈希字符串值:0
我的 hashstring 值:3003 // 在 getHash 中打印:这是预期的
我的 hashstring 值:0

我已经尝试通过在 foo() 中打印哈希字符串的指针来进行调试。似乎在每次调用中,我都得到了相同的哈希字符串地址。

打印出来的内容如下:
0x7ffee1992f54
0x7ffee1992f54
0x7ffee1992f54

我猜这可能意味着我在 getHash() 中以某种方式引用了相同的哈希字符串变量,这很奇怪,因为我每次都在创建一个新变量。我还尝试了其他变体,例如 getHash() 中的 snprintf(hashstring, 12, "%d", hashint),或者创建一个 char *pointerToHash 并将 *pointerToHash 传递给 sprintf。

有什么想法吗?

【问题讨论】:

  • 请发帖minimal reproducible example。缩进也有帮助。
  • 首先,在两个不同的函数中使用同名的局部变量会造成混淆。 getHash 中的数组hashstring 是本地的,当getHash 返回时,它的生命周期结束。所以返回它的地址会导致main 不能使用的指针。如您所见,该记忆可能随时被其他内容覆盖。一个好的编译器应该给你警告。
  • 请给minimal reproducible example,重点是完整

标签: c debugging scope undefined-behavior


【解决方案1】:

这个函数

char* getHash(Obj *obj) {
...
int hashint = getHashInt(args);
// I am trying to do a conversion from int to string here
char hashstring[12]; 
sprintf(hashstring, "%d", hashint);
printf("My value of hashstring: %s\n", &hashstring);
return &hashstring;
}

调用未定义的行为,因为它返回一个指向本地数组的指针

 char hashstring[12]; 

退出函数后将不再存在。

此外,函数char *的返回类型和返回表达式char ( * )[12]的类型不同,并且没有从一种类型到另一种类型的隐式转换。

为了避免这个问题,你应该动态分配数组,例如

char *hashstring = calloc( 12, sizeof( char ) );

在return语句中写

return hashstring;

然后在调用者中,当不再需要分配的数组时,您应该释放分配的内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-03
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多