首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >堆栈内存可以在函数中自动分配吗?

堆栈内存可以在函数中自动分配吗?
EN

Stack Overflow用户
提问于 2013-10-10 17:05:05
回答 3查看 567关注 0票数 6

很抱歉之前有人问过,但我什么都没找到.

对于“正常”的x86体系结构:

当我在C++中调用一个大函数时,内存是否立即分配给所有堆栈变量?或者,即使函数尚未完成,也有编译器可以(并且确实)修改堆栈大小。

例如,如果一个新范围启动:

代码语言:javascript
复制
int largeFunction(){
    int a = 1;
    int b = 2;

    // .... long code ....

    { // new scope

         int c = 5;

         // .... code again ....

    }

    // .....

}

调用堆栈是否也会在独立作用域开始时对变量c“增长”,而在其结束时“收缩”?还是当前编译器总是生成影响函数输入和返回值的堆栈指针的代码?谢谢你的提前答复。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-10-10 17:24:44

1)函数的时间长短与内存的分配无关,与堆栈或堆无关。

2)当堆栈被“分配”时,只取决于编译器做出最有效代码的方式。“高效”有广泛的要求。所有编译器都有修改优化器目标的选项,用于速度和大小,而且大多数编译器还可以优化堆栈消耗和其他参数。

3)自动变量可以放在堆栈上,但这不是必须的。许多变量应该“分配”到cpu的寄存器中。这大大加快了代码的速度,并节省了堆栈。但这在很大程度上取决于cpu平台。

4)当编译器生成一个新的堆栈帧时,也是一个代码优化问题。编译器可以执行“无序执行”,如果这样可以节省资源或更符合体系结构的话。因此,当堆栈帧开始使用时,无法回答这个问题。一个新的作用域(打开大括号)可以作为分配新堆栈框架的重点,但这绝不是一个保证。有时,从实际作用域重新计算所有被调用函数的所有堆栈相对地址是不有效的。

5)一些编译器也可以将堆内存用于自动变量。如果通过特殊指令进行访问的速度比堆栈相对寻址更快,则在嵌入式内核上经常会出现这种情况。

但通常情况下,编译器做他想做的事情并不是很重要。有时候唯一需要记住的是,你必须保证你的堆栈足够大。通常,对新线程的系统调用具有设置堆栈大小的参数。因此,您必须知道您的实现需要多少堆栈大小。但在所有其他情况下:忘记去想。这个工作是从您的编译器开发人员完美完成的。

票数 8
EN

Stack Overflow用户

发布于 2013-10-10 17:30:46

我不知道答案(我希望您只想知道,因为您很好奇,因为没有一个有效的程序能够分辨出不同之处),但是您可以通过在新作用域之前调用这样的函数并在新作用域之后再次调用这样的函数来测试编译器的行为:

代码语言:javascript
复制
std::intptr_t stackaddr()
{
    int i;
    return reinterpret_cast<std::intptr_t>(&i);
}

如果得到相同的结果,那么这意味着在创建c之前已经对堆栈进行了调整。

G++ 4.7中有一个变化,允许编译器在其作用域结束后重用c的堆栈空间,在此之前,任何新的变量都会增加堆栈的使用率:"G++现在正确地重新使用在临时对象生命周期结束时分配给它们的堆栈空间,这可以大大降低某些C++函数的堆栈消耗。“,但我认为这只会影响函数入口时保留了多少堆栈,而不是在什么时候/什么地方保留它。

票数 3
EN

Stack Overflow用户

发布于 2013-10-10 17:34:43

这完全取决于您正在使用的系统的运行时约定,然而,CPU体系结构通常在决策中起着很大的作用,因为该体系结构定义了可以安全使用的堆栈管理。例如,在MacOS X下的旧PowerPC上,堆栈帧总是固定大小的,新堆栈帧低端的堆栈指针的原子存储就会分配它,取消对堆栈指针的引用相当于弹出整个堆栈帧。

当前的系统,如Linux和(如果我错了),x86上的Windows有一种更动态的方法,使用原子推送和pop指令(在PowerPC上没有原子pop ),其中函数调用的参数在每个函数调用之前被推入堆栈,有效地调整了每次分配的堆栈帧的大小。

因此,是的,在许多当前系统上,编译器可以调整堆栈帧的大小,但在其他系统中,这样的操作至少是很难完成的(但绝不是不可能的)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19301963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档