函数的堆栈分配
Stack Allocation For Functions
是否对模块/源文件中关于内存分配的函数进行了量化测试,如以下32位构建所示:
#include <windows.h>
int main()
{
wchar_t TestArray [516332] = { NULL };
}
它对516332(或7E0EC)成功,但对516333产生堆栈溢出。当然,2Gb或7FFFFFFF的全球跌幅是合法的,但加一个就可以得到SO。
#include <windows.h>
wchar_t TestArray [2147483647] = { NULL };
int main()
{
}
在32位构建中使用VS10/MCBS,但X64的表现并不好。在64或128系统中,函数类型(例如long、char void、bool)是否按比例增加?特别是用数字/表格法搜索答案。
不确定我是否答对了你的问题,但是:
int main()
{
wchar_t TestArray [516332] = { NULL };
}
在这里,您达到了默认1MB线程堆栈大小的限制(堆栈上也会有其他一些数据)。默认大小可以在Visual Studio中使用/STACK:reserve[,commit]
进行调整。
wchar_t TestArray [2147483647] = { NULL };
int main()
{
}
在这里,您在32位系统上达到了2GB用户模式的限制(可以使用/3GB启动开关进行更改)。
简短的回答是"否"。没有办法"检查"有多少可用的堆栈空间,或者堆栈有多大。一些运行时系统知道堆栈空间,但没有标准,从技术上讲,C++标准(或C标准)甚至没有规定应该有这样的堆栈(尽管在没有某种堆栈的情况下构建系统会相当困难,但从技术上讲,它不必是堆栈指针的硬件寄存器,参数传递可以完全通过其他机制来完成)。
在64位系统中有一个更大的堆栈在技术上是可能的-我认为还没有人开始考虑真正的128位系统-我们有一个公平的方法,直到当前系统用完64位中的可用位-当前内存映射只能处理53位-要获得更多,页表处理需要更改。目前的处理器往往实际实现了48位内存地址,这仍然提供65536*4GB,即256TB。由于当前系统的最大容量为1-2TB,在耗尽当前可用容量之前,我们还有相当长的路要走。
尽管从技术上讲,即使在32位环境中,堆栈大小也可能大得多,但通常限制在几兆字节以内。对于大量数据,您希望使用堆,因为堆的限制要小得多,如果确实用完了,则可以进行恢复,而堆栈空间用完通常不是这样[在函数中使用大量堆栈通常是不好的,因为该函数的其他"消费者"可能没有意识到它使用了多少内存]。对于高达几百字节的小变量,从堆中分配的开销是显而易见的,但对于非常大的对象,如几十万wchar_t
,在堆中分配它的开销是微不足道的,因此这将是"正确"的做法
对于类似字符串的东西,我建议:
std::wstring TestString(size);
假设您有一个所需的大小,它将允许您以该大小分配单个字符串,并且最大大小受可用内存和最大分配大小(取决于系统,但应至少为2GB左右)的组合限制。
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 从堆栈分配的原始指针构造智能指针
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- 巨大的内存分配:堆栈与堆
- 有效地分配堆栈对象(由函数的值返回)到堆?
- 为什么不能在 Visual C++ 中动态分配堆栈内存?但海湾合作委员会可以做到
- 为什么分配堆内存比分配堆栈记忆更快
- 安全分配堆栈分配的阵列
- 附加到具有非动态分配堆栈的向量
- 是否随作用域分配和解除分配堆栈帧
- 在执行中脱离堆栈对象的范围之前,请分配堆栈对象
- 全局阵列分配 -- 堆栈或堆
- 如何使新操作员超载以分配堆栈
- 具有类作用域的动态分配堆栈内存
- 如何在 Linux 下为可执行文件分配堆栈
- 内存分配堆栈
- 成员函数内存分配堆栈或堆
- 在 c++ 中重新分配堆栈上的对象
- 防止为类和派生类分配堆栈
- 如何防止msvc++为switch语句过度分配堆栈空间?