8

我正在使用 Visual Studio 2010 Win 8。我有一个类,我正在制作一个二维数组来保存游戏的游戏数据。

创建一个空白控制台应用程序并制作 main.cpp 并添加此代码。对 MAP_SIZE 使用 360 会导致堆栈溢出,而使用 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;
}
4

5 回答 5

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]
};
于 2012-12-20T18:11:39.767 回答
5

Tile您正在堆栈上分配 360 x 360 对象的数组。这从一开始就是一个坏主意。您在堆栈上分配了一个非常大的内存块。堆栈不适用于此类用途。

如果您只需要一个实例并且事先知道大小,则此内存应该是静态的,或者您应该从堆中分配它(使用new或什至malloc())。

考虑使用构造函数来Server分配内存,new而不是按照您的操作方式进行操作。

于 2012-12-20T18:12:11.637 回答
4

堆栈的大小有限。如果您需要容纳一个大数组,请使用动态分配。

于 2012-12-20T18:10:46.343 回答
4

您创建了一个类型,每个实例需要约 1MB 的堆栈空间,这显然比您的堆栈可以容纳的要大。

  • 可移植选项是从固定数组更改为动态分配或向量类型。
  • 不可移植的选项是增加应用程序中的堆栈大小(这反过来会增加所有线程的堆栈大小)
于 2012-12-20T18:11:54.007 回答
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

  • 右键单击项目,然后从菜单中选择属性。
  • 进入配置属性->C/C++->命令行,添加这个参数:

    /F801000000

在此处输入图像描述

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

    /堆栈:801000000

在此处输入图像描述

完毕!

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

于 2014-02-01T00:40:33.313 回答