函数的堆栈分配
Stack Allocation For Functions
modules/source 文件中关于内存分配的函数是否有任何定量测试,如以下 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)是否按比例增加?专门使用 numerical/tableau 方法搜索答案。
简答为 "no"。无法 "check" 有多少 stack-space 可用,或者堆栈有多大。一些 运行 时间系统具有堆栈的知识 space,但是没有这方面的标准,从技术上讲,C++ 标准(或 C 标准)甚至没有规定应该有堆栈因此(尽管在没有某种堆栈的情况下构建系统会相当困难,但从技术上讲,它不必是堆栈指针的硬件寄存器,并且参数传递可以完全通过其他机制完成)。
在 64 位系统中拥有更大的堆栈在技术上是可能的 - 我认为还没有人开始考虑真正的 128 位系统 - 在当前系统用完之前我们有一个公平的方法64 位中的可用位 - 当前内存映射只能处理 53 位 - 要获得更多位,需要在 page-table 处理中进行更改。目前的处理器往往实际实现了 48 位内存地址——这仍然提供 65536 * 4GB,或 256TB。当前系统的最大容量为 1-2TB,在我们 运行 超出当前可用容量之前,我们还有很长的路要走。
尽管技术上可能更大,但即使在 32 位环境中,堆栈大小通常也限制在几兆字节以内。对于大量数据,您希望使用堆,它的限制要少得多 - 如果您执行 运行 out,则可以恢复,这通常不是 运行ning out 的情况stack-space [并且在函数中使用大量堆栈通常是不好的,因为该函数的其他 "consumers" 可能没有意识到它使用了多少内存]。对于小变量,最多几百字节,从堆上分配的开销会很明显,但是对于非常大的对象,比如几十万 wchar_t
,在堆上分配它的开销是微不足道的,所以这就是 "right" 要做的事情。
对于某事string-like,我建议:
std::wstring TestString(size);
假设您有所需的大小 - 它将允许您分配该大小的单个字符串,并且最大大小受可用内存和最大分配大小的组合限制(这取决于系统,但应该至少 2GB 左右)。
不确定我是否答对了你的问题,但是:
int main()
{
wchar_t TestArray [516332] = { NULL };
}
此处您正在达到默认 1MB 线程堆栈大小的限制(一些其他数据也已经在堆栈中)。可以使用 /STACK:reserve[,commit]
in Visual Studio.
调整默认大小
wchar_t TestArray [2147483647] = { NULL };
int main()
{
}
您在 32 位系统上达到了 2GB 用户模式限制(可以使用 /3GB 启动开关更改)。
modules/source 文件中关于内存分配的函数是否有任何定量测试,如以下 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)是否按比例增加?专门使用 numerical/tableau 方法搜索答案。
简答为 "no"。无法 "check" 有多少 stack-space 可用,或者堆栈有多大。一些 运行 时间系统具有堆栈的知识 space,但是没有这方面的标准,从技术上讲,C++ 标准(或 C 标准)甚至没有规定应该有堆栈因此(尽管在没有某种堆栈的情况下构建系统会相当困难,但从技术上讲,它不必是堆栈指针的硬件寄存器,并且参数传递可以完全通过其他机制完成)。
在 64 位系统中拥有更大的堆栈在技术上是可能的 - 我认为还没有人开始考虑真正的 128 位系统 - 在当前系统用完之前我们有一个公平的方法64 位中的可用位 - 当前内存映射只能处理 53 位 - 要获得更多位,需要在 page-table 处理中进行更改。目前的处理器往往实际实现了 48 位内存地址——这仍然提供 65536 * 4GB,或 256TB。当前系统的最大容量为 1-2TB,在我们 运行 超出当前可用容量之前,我们还有很长的路要走。
尽管技术上可能更大,但即使在 32 位环境中,堆栈大小通常也限制在几兆字节以内。对于大量数据,您希望使用堆,它的限制要少得多 - 如果您执行 运行 out,则可以恢复,这通常不是 运行ning out 的情况stack-space [并且在函数中使用大量堆栈通常是不好的,因为该函数的其他 "consumers" 可能没有意识到它使用了多少内存]。对于小变量,最多几百字节,从堆上分配的开销会很明显,但是对于非常大的对象,比如几十万 wchar_t
,在堆上分配它的开销是微不足道的,所以这就是 "right" 要做的事情。
对于某事string-like,我建议:
std::wstring TestString(size);
假设您有所需的大小 - 它将允许您分配该大小的单个字符串,并且最大大小受可用内存和最大分配大小的组合限制(这取决于系统,但应该至少 2GB 左右)。
不确定我是否答对了你的问题,但是:
int main()
{
wchar_t TestArray [516332] = { NULL };
}
此处您正在达到默认 1MB 线程堆栈大小的限制(一些其他数据也已经在堆栈中)。可以使用 /STACK:reserve[,commit]
in Visual Studio.
wchar_t TestArray [2147483647] = { NULL };
int main()
{
}
您在 32 位系统上达到了 2GB 用户模式限制(可以使用 /3GB 启动开关更改)。