c - 在堆栈上构造保持上次函数调用的先前值
问题描述
我有一个结构:
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
给成员赋值时,该成员的值是不确定的。编译器可以自由地从之前某个函数调用中留在堆栈中的任何值中获取值。
初始化不会导致成员tmp
的值保持不变。它将这些成员设置为零。要保持成员的值不变,您可以从以下位置初始化:memset
globalStruct = tmp;
setStruct
tmp
globalStruct
static void myFunc()
{
myStruct tmp = globalStruct;
setStruct(&tmp);
globalStruct = tmp;
return;
}
另一种可能性是您可以直接更新globalStruct
:
static void myFunc()
{
setStruct(&globalStruct);
}
推荐阅读
- recursion - java中的递归函数?
- fopen - 使用 DD 名称时重命名文件
- python - 在 python pandas 中使用 loc 时出错
- javascript - 如何扩展一个看起来像这样的 javascript 对象:`export default { ... }`
- flutter - 如果我的设备在 Flutter 中支持人脸和指纹认证,local_auth 默认会选择什么?
- python - 如何在 python 中使用 hdbcli 执行 SQL 脚本
- javascript - jquery在错误条件下停止表单提交
- c++ - 消费者和生产者问题的双缓冲
- python - 运行python文件时找不到opencv模块
- opengl - 将变换矩阵与法向量相乘时的奇怪行为