使用2D数组的C ++ Visual Studio堆栈溢出

时间:2012-12-20 18:08:13

标签: c++ visual-studio-2010 stack-overflow

我正在使用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;
}

5 个答案:

答案 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

enter image description here

  • 转到配置属性 - &gt;链接器 - &gt;命令行,添加此参数

    / STACK:8.01亿

enter image description here

完成!

3-第三种解决方案是动态数组,用于分配堆,而不是静态数组,正如所有人所说的那样。