-1

假设我在 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

4

1 回答 1

4

因为退出pmem后不再指向有效的内存区域。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;
}

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

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

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

但是你必须记住释放这个指针,否则你会造成内存泄漏

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

(另请参阅堆栈和堆是什么以及在哪里?堆栈与堆。)

于 2012-09-28T13:48:12.580 回答