我正在使用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;
}
答案 0 :(得分:8)
我的估计值sizeof(Tile)
为8或更高。这意味着sizeof(Server)
至少为360 * 360 * 8 = 1036800,即0.99 MB。堆栈通常很小,1MB是常见的默认大小。您应该在堆上分配切片,可能使用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]
};
答案 1 :(得分:5)
您正在堆栈中分配360 x 360 Tile
个对象的数组。从一开始就是一个坏主意。您在堆栈上分配了一个非常大的内存块。堆栈不适用于此类用途。
如果你只需要一个实例并且事先知道大小,那么这个内存应该是静态的,或者你应该从堆中分配它(使用new
甚至malloc()
)。
考虑让Server
的构造函数使用new
分配内存而不是按照你的方式进行操作。
答案 2 :(得分:4)
堆栈的大小有限。如果你需要一个大数组,请使用动态分配。
答案 3 :(得分:4)
你创建了一个类型,每个实例需要大约1MB的堆栈空间,这显然比你的堆栈可以容纳的大。
答案 4 :(得分:0)
默认堆栈大小为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
转到配置属性 - &gt; C / C ++ - &gt;在命令行中,添加以下参数:
/ F801000000
转到配置属性 - &gt;链接器 - &gt;命令行,添加此参数
/ STACK:8.01亿
完成!
3-第三种解决方案是动态数组,用于分配堆,而不是静态数组,正如所有人所说的那样。