首页 > 解决方案 > 在堆栈上构造保持上次函数调用的先前值

问题描述

我有一个结构:

typedef struct
{
  int a;
  char str[9];
} myStruct;

我有这个结构的全局变量:

myStruct globalStruct;

然后我有一个经常被调用的函数,它是唯一真正globalStruct改变的方法:

static void myFunc()
{
  myStruct tmp;
  setStruct(&tmp);
  globalStruct = tmp;
  return;
}

有时会更改结构中的setStruct两个字段,有时只会更改myStruct.a。我看到的问题是,即使tmp在我认为是堆栈的地方声明了它实际上保留了前一个函数调用的值,如果我不设置myStruct.str它只会将前一个值放入globalStruct. 我知道这个问题可以通过做memset(tmp, 0x0, sizeof(tmp))我的问题来解决,更多的是为什么会发生这种情况?我以为tmp函数结束后内存会被释放。

标签: cmemory

解决方案


myStruct tmp;创建一个“新”myStruct并且不初始化它。C 标准没有定义它的值(即它的成员的值)。

当既不给成员赋值myFunc也不setStruct给成员赋值时,该成员的值是不确定的。编译器可以自由地从之前某个函数调用中留在堆栈中的任何值中获取值。

初始化不会导致成员tmp的值保持不变。它将这些成员设置为零。要保持成员的值不变,您可以从以下位置初始化:memsetglobalStruct = tmp;setStructtmpglobalStruct

static void myFunc()
{
  myStruct tmp = globalStruct;
  setStruct(&tmp);
  globalStruct = tmp;
  return;
}

另一种可能性是您可以直接更新globalStruct

static void myFunc()
{
  setStruct(&globalStruct);
}

推荐阅读