堆栈上的结构保留上次函数调用的先前值
Struct on the stack keeping previous value from last function call
我有一个结构:
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
中的内存会在函数结束后被释放。
myStruct tmp;
创建一个“新的”myStruct
并且不初始化它。 C标准没有定义它的值(即它的成员的值)。
当myFunc
和setStruct
都没有给成员赋值时,该成员的值是不确定的。编译器可以自由地从之前的函数调用中留在堆栈中的任何值中获取值。
用 memset
初始化 tmp
不会导致 globalStruct = tmp;
保持成员的值未被 setStruct
更改。它会将这些成员设置为零。要保持成员的值不变,您可以从 globalStruct
:
初始化 tmp
static void myFunc()
{
myStruct tmp = globalStruct;
setStruct(&tmp);
globalStruct = tmp;
return;
}
另一种可能性是您可以直接更新 globalStruct
:
static void myFunc()
{
setStruct(&globalStruct);
}
我有一个结构:
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
中的内存会在函数结束后被释放。
myStruct tmp;
创建一个“新的”myStruct
并且不初始化它。 C标准没有定义它的值(即它的成员的值)。
当myFunc
和setStruct
都没有给成员赋值时,该成员的值是不确定的。编译器可以自由地从之前的函数调用中留在堆栈中的任何值中获取值。
用 memset
初始化 tmp
不会导致 globalStruct = tmp;
保持成员的值未被 setStruct
更改。它会将这些成员设置为零。要保持成员的值不变,您可以从 globalStruct
:
tmp
static void myFunc()
{
myStruct tmp = globalStruct;
setStruct(&tmp);
globalStruct = tmp;
return;
}
另一种可能性是您可以直接更新 globalStruct
:
static void myFunc()
{
setStruct(&globalStruct);
}