【问题标题】:C struct is only working when there is a printf with declarative methodC struct 仅在存在带有声明性方法的 printf 时才有效
【发布时间】:2012-09-28 13:45:33
【问题描述】:

假设我在 temp.h 中声明了一个结构,如下所示:

/* physical memory */
typedef struct pmem_struct {
 uint32_t val;
} pmem_s, *pmem_p;

假设我在我的 temp.c 文件中的方法 pmem_p pmem_new() 中声明了这个结构,如下所示:

 pmem_p pmem_new() {
  pmem_s pmems;
  pmem_p pmem = &pmems;
  pmem->val = 0;
  //printf(stderr, "From Mem: %x\n", pmem->val);
  return pmem;
}

现在这是我的 main.c 文件:

#include <stdio.h>

#include "temp.h"
#include "gen.h"

int main() {
    pmem_p pmem = pmem_new(); /* create some physical memory */
    fprintf(stderr, "From Mem: %x\n", pmem->val);
......
}

为什么这个 fprintf 打印出 From Mem: 4019cff4,除非我在 pmem_new() 中取消注释 fprintf 行,在该行处两者都正确打印出 From Mem:0强>

【问题讨论】:

  • 你返回一个指向在函数结束时被销毁的局部变量的指针。因此返回的指针无效。

标签: c pointers struct printf


【解决方案1】:

因为在pmem_new() 退出后,pmem 不再指向有效的内存区域。您看到的是未定义的行为。

 pmem_p pmem_new() {
  pmem_s pmems;
  pmem_p pmem = &pmems;
  pmem->val = 0;
  //printf(stderr, "From Mem: %x\n", pmem->val);
  return pmem;
}

在这里,您在函数pmem_new() 范围内的“堆栈”上分配pmems。使用“堆栈分配”,一旦程序离开周围范围,内存将变得无效。因此,在离开函数pmem_new() 后,指向pmems 的指针将变为dangling pointer

您可以通过在“堆”上分配内存来解决它,除非您手动这样做,否则内存不会被破坏。在 C 中,这是通过 malloc 方法完成的:

pmem_p pmem_new_correct() {
  pmem_p pmem = malloc(sizeof(*pmem));
  pmem->val = 0;
  return pmem;
}

但是你必须记住释放这个指针,否则你会创建一个memory leak

int main() {
  pmem_p pmem = pmem_new();
  fprintf(stderr, "From Mem: %x\n", pmem->val);
  ......
  free(pmem);
}

(有关堆栈与堆的信息,另请参阅 What and where are the stack and heap?。)

【讨论】:

  • @user1706394:不,不是全局变量,请参阅 KennyTM 的更新(或在 main 中创建一个结构变量(不仅仅是指针),这与全局变量不同)。
猜你喜欢
  • 1970-01-01
  • 2011-06-29
  • 2021-08-22
  • 1970-01-01
  • 1970-01-01
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多