c++读取上一个函数堆栈帧
c++ reading previous function stack frame
我有一个由函数创建的数组(名为write)。在该函数返回后,我调用另一个函数(名为read),该函数直接从堆栈中读取相同大小的数组。
#include <iostream>
using std::cout;
using std::endl;
void write();
void read();
int main(void)
{
write();
read();
return 0;
}
// Write an array of 10 ints to the stack
void write() {
int array[10];
for(int i = 0; i < 10; i++)
array[i] = i;
}
// Read an array of 10 from stack
void read() {
int array[10];
for(int i = 0; i < 10; i++)
cout << array[i] << endl;
}
read函数不应该从堆栈中读取相同的数组内容吗?
我发现有趣的是,第一个和第二个数组值总是相同的。第一个(在索引0处)是一个负垃圾值。第二个(位于索引1处)为0。
据我所知,当一个函数返回时,它不会清理它的堆栈框架。因此,当read读取堆栈时,它读取的值与write写入的值相同。但是为什么第一个和第二个值总是这样?
正如其他人所指出的,这种行为是完全未定义的,所以即使你运行了1000次这个代码并看到了这种行为,你也可能在第1001次看到不同的东西。此外,您所看到的内容和原因将非常依赖于实现。如果你真的很想更好地理解这一点,我建议你看看编译器生成的汇编代码,你会更好地了解堆栈的情况。同样,如何做到这一点取决于实现,但使用gcc,您可以将--save-temps
选项传递给编译器,它会吐出中间文件供您仔细阅读。这很有教育意义!
数组在堆栈空间中占据相同的一般邻域,但这只是巧合。如果read()或write()中有更多的变量,那么情况就不再是这样了。堆栈框架的结构是编译器中的一个实现细节-它取决于许多事情,如函数中的变量、优化级别、编译器可能在堆栈上分配的临时存储空间、为函数或其被调用者可能抛出的异常展开数据。。。简而言之,永远不要依赖它。
从C++标准的角度来看,从未初始化的变量(如read
中的array
)中读取是一种未定义的行为——从获取伪值到程序崩溃,任何事情都可能发生。
相关文章:
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- "main"函数堆栈中的对象在第一个任务运行时被覆盖 (FreeRTOS)
- 提升堆栈跟踪不显示函数名称和行号
- C++析构函数调用两次,堆栈分配的复合对象
- 静态堆栈函数不会 1) 输入第一个元素 2)添加新元素时识别旧元素
- 以下代码如何工作以每次为唯一调用堆栈唯一实例化模板函数?
- 如何修复递归函数导致的堆栈溢出错误?C++
- 如果类在堆上,函数是转到堆还是堆栈?
- C++ 中的构造函数、继承、堆栈、堆、this-pointer 和段错误
- 何时在函数中声明堆栈分配变量?
- 使用在堆栈上创建的对象调用虚拟函数
- 为什么析构函数无休止地调用自己(导致堆栈溢出)?
- 双链表堆栈删除函数不起作用
- 函数,该函数将在堆栈底部保留最小的出现次数
- 我正在尝试使用递归来反转堆栈.函数 fun() 中传递了什么?s 是类堆栈的对象
- Visual C++ 堆栈函数和错误处理
- 如何知道堆栈函数消耗了多少
- 如何在这个无锁堆栈函数中防止未定义的行为和ABA问题
- 打印堆栈函数
- 堆栈函数应该返回指定的元素,而不是返回垃圾值