当前位置:  开发笔记 > 编程语言 > 正文

关于C/C++堆栈分配

如何解决《关于C/C++堆栈分配》经验,为你挑选了5个好方法。

在学习C++(和C)时,我对堆栈分配的工作有一些特别的疑问,我无法找到解决方案:

    堆栈分配是否隐式调用malloc/free函数?如果不; 它如何确保堆栈分配和堆分配之间没有冲突?

    如是; C++中的堆栈分配是否也隐式调用new/delete?如是; 重载一个类的new运算符会影响它的堆栈分配吗?

它在VC++中产生了令人困惑的结果; 但由于VC++并不完全符合标准(或者我听说过),我决定在这里问一下......



1> sharptooth..:

堆栈分配不使用malloc/free之类的东西.它使用一段称为程序堆栈的内存,它只是一段连续的内存.

有一个特殊的寄存器存储堆栈的顶部.当在堆栈上创建新对象时,顶部被抬起从而增加堆栈,当对象被解除分配(超出范围)时,顶部被降低从而减少堆栈.

如果您尝试在堆栈上分配太大的对象或者过于深入递归,则顶部将超出堆栈的最大允许大小,这称为堆栈溢出.

注意:堆栈增长的实际方向(增加或减少地址)将因系统而异,但无论实际方向如何,总体思路都是相同的.



2> Suma..:

第一个问题的答案是否.堆栈根本没有从堆中分配.

您应该首先阅读堆栈和堆的内容和位置以了解基本概念.



3> plinth..:

堆栈分配通常根据alloca()或由编译器隐式完成.一个做得好的alloca()只需要很少的指令,并且在你完成时没有任何成本(甚至是需要)来释放它.

您可以将指向alloca()分配的内存的指针传递给任何其他需要指针的函数/方法.你必须永远不要返回alloca()分配的指针.

以下是使用堆栈分配的一些优点和缺点.



4> Daniel Earwi..:

这里有一个很好的问题:

"它如何确保堆栈分配和堆分配之间没有冲突?"

几乎所有C/C++实现中都有一个连续的地址空间,因此堆栈和堆分配的内存必须在该空间中共存.

虽然每次堆栈增长和收缩时都不会使用单个堆分配,但您仍然可以将堆栈视为从堆分配的单个大块内存.如果堆栈超出了该块的边界,那么我们就会有一个堆栈溢出(引人注目的名字......有人应该在它之后命名一个网站).

在多线程程序中,每次线程启动时,都必须为它分配一个新堆栈,当线程死亡时,可以释放堆栈.并且使用与通过malloc/ 公开的相同堆管理来分配那些整个堆栈块是有意义的free.

所以 - 非常接近 - 你可以认为堆栈是一种在堆中共存的对象.malloc当一个线程启动时,整个堆栈都被一次性完成,然后它被子分配,然后free一次性得到-d.

在Windows上,您可以(如果您喜欢危险地生活)自己调用相同的虚拟内存API来查找堆栈并强制释放其中的虚拟页面.



5> Pete Kirkham..:

在C和C++中,存在两种类型的内存分配"自动",其中对象是在函数调用的生命周期中创建的,而"动态"则是由运行时提供的函数分配的.

在绝大多数运行时实现中,在创建线程时使用操作系统提供的连续堆栈分配自动对象.堆栈通常从高值地址开始,并按对象的大小递减.动态分配(C中的malloc,C++中的new)使用操作系统请求的其他一些内存.由于操作系统知道堆栈正在使用的地址,因此它不会为动态请求分配相同的地址.由于动态区域没有排序,因此通常称为堆.

所以'堆栈'分配不是malloc/free.C++中的自动对象调用构造函数和析构函数,但不是new或delete,因为new和delete也有管理动态内存的代码.

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有