函数的堆栈分配

Stack Allocation For Functions

本文关键字:分配 堆栈 函数      更新时间:2023-10-16

是否对模块/源文件中关于内存分配的函数进行了量化测试,如以下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左右)的组合限制。