[英]C++ Visual Studio stack overflow with 2D array
我正在使用Visual Studio 2010 Win 8.我有一个类,我正在制作一个2D数组来保存游戏的游戏数据。
创建一个空白控制台应用程序并生成main.cpp并添加此代码。 使用360 for MAP_SIZE导致堆栈溢出使用359不会。 为什么会这样? 我希望有一个更大尺寸的阵列。 我想要像2000 - 10,000这样理想的东西。
#define MAP_SIZE 360
typedef unsigned short ushort;
typedef unsigned long ulong;
struct Tile
{
ushort baseLayerTileID;
ulong ownerID;
};
class Server
{
private:
Tile _map[MAP_SIZE][MAP_SIZE];
};
int main()
{
Server s;
return 0;
}
我的估计将sizeof(Tile)
8或更高。 这意味着sizeof(Server)
至少为360 * 360 * 8 = 1036800,即0.99 MB。 堆栈通常很小,1MB是常见的默认大小。 你应该在堆上分配tile,也许使用std::vector
。
class Server
{
public:
Server() : _map(MAP_SIZE * MAP_SIZE) {}
private:
std::vector<Tile> _map; // position [i][j] is at [i*MAP_SIZE+j]
};
您正在堆栈上分配一个360 x 360 Tile
对象的数组。 从一开始就是一个坏主意。 您在堆栈上分配了一个非常大的内存块。 堆栈不适用于此类用途。
如果你只需要一个实例并且事先知道它的大小,那么这个内存应该是静态的,或者你应该从堆中分配它(使用new
或甚至malloc()
)。
考虑让Server
的构造函数使用new
分配内存,而不是按照你的方式进行操作。
堆栈的大小有限。 如果需要保存大数组,请使用动态分配。
您创建了一个类型,每个实例需要大约1MB的堆栈空间,这显然比您的堆栈可以容纳的大。
默认堆栈大小为1MB。 你的struct size = ushort(2bytes)+ ulong(4byte)= 6个字节,编译器将其转换为8个字节以进行结构对齐。 所以8 * 360 * 360 = 1036800字节,略高于1MB
有3种解决方案:
1-强制停止对齐:
#pragma pack(push) /* push current alignment to stack */
#pragma pack(1) /* set alignment to 1 byte boundary */
struct Tile
{
ushort baseLayerTileID;
ulong ownerID;
};
#pragma pack(pop) /* restore original alignment from stack */
这将允许最大MAP_SIZE = sqrt(1024 * 1024/6)= 418,因此这允许更大的地图大小但不允许你想要的大小
2 - 您可以更改visual studio设置以允许编译器和链接器在堆栈中使用超过1 MB:您需要将其更改为您需要的最大地图大小,即8 * 10000 * 10000~800MB
转到配置属性 - > C / C ++ - >命令行,添加此参数:
/ F801000000
转到配置属性 - >链接器 - >命令行,添加此参数
/ STACK:8.01亿
完成!
3-第三个解决方案是动态数组,用于分配堆,而不是静态数组,正如所有人所说的那样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.