在此处的第一个答案中,提到了关于C++中堆栈内存的以下内容:
“当调用函数时,在堆栈顶部保留一个块以用于局部变量和一些簿记数据。”
这在顶层上很有道理,并且让我对编译器在分配内存方面的智能程度产生了好奇,考虑到这个问题的背景: 由于花括号本身在C中不是一个堆栈帧(我认为这同样适用于C ++),我想检查编译器是否会根据单个函数内变量作用域优化保留的内存。
在接下来的内容中,我假设函数调用前堆栈的样子如下:
在调用函数
例如,给定以下函数:
忽略编译器优化,因为实际上它们并没有做什么,我对第二个示例中的以下内容很感兴趣:
“当调用函数时,在堆栈顶部保留一个块以用于局部变量和一些簿记数据。”
这在顶层上很有道理,并且让我对编译器在分配内存方面的智能程度产生了好奇,考虑到这个问题的背景: 由于花括号本身在C中不是一个堆栈帧(我认为这同样适用于C ++),我想检查编译器是否会根据单个函数内变量作用域优化保留的内存。
在接下来的内容中,我假设函数调用前堆栈的样子如下:
--------
|main()|
-------- <- stack pointer: space above it is used for current scope
| |
| |
| |
| |
--------
在调用函数
f()
之后,接下来会执行以下内容:--------
|main()|
-------- <- old stack pointer (osp)
| f() |
-------- <- stack pointer, variables will now be placed between here and osp upon reaching their declarations
| |
| |
| |
| |
--------
例如,给定以下函数:
void f() {
int x = 0;
int y = 5;
int z = x + y;
}
可以推测,这将只分配3*sizeof(int)
的空间加上一些额外的开销用于记录。
但是,对于这个函数呢:
void g() {
for (int i = 0; i < 100000; i++) {
int x = 0;
}
{
MyObject myObject[1000];
}
{
MyObject myObject[1000];
}
}
忽略编译器优化,因为实际上它们并没有做什么,我对第二个示例中的以下内容很感兴趣:
- 对于for循环:堆栈空间是否足够容纳所有100000个整数?
- 除此之外,堆栈空间是否包含1000*sizeof(MyObject)或2000*sizeof(MyObject)?
总的来说,编译器在调用某个函数之前,会考虑变量作用域以确定需要多少内存来创建新的堆栈帧吗? 如果这是与编译器有关的,请问一些知名的编译器是如何处理的?
{}
是一个作用域。 循环重复使用相同的内存来存储x
,同时两个myObject
数组不会同时存在。 - LogicStuff100000
个整数分配空间?数组也是同样的道理。 - Algirdas Preidžius