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

C++ C++;使用2D数组的Visual Studio堆栈溢出,c++,visual-studio-2010,stack-overflow,C++,Visual Studio 2010,Stack Overflow,我使用的是Visual Studio 2010 Win 8。我有一个类,我正在制作一个2D数组来保存游戏数据 创建一个空白的控制台应用程序,生成main.cpp并添加此代码。使用360表示贴图大小会导致堆栈溢出,而使用359则不会。为什么会这样?我希望有一个更大的数组。理想情况下,我想要2000-10000左右 #define MAP_SIZE 360 typedef unsigned short ushort; typedef unsigned long ulong; struct Til

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

创建一个空白的控制台应用程序,生成main.cpp并添加此代码。使用360表示贴图大小会导致堆栈溢出,而使用359则不会。为什么会这样?我希望有一个更大的数组。理想情况下,我想要2000-10000左右

#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.99MB。堆栈通常很小,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]
};
类服务器
{
公众:
服务器():_映射(映射大小*映射大小){}
私人:
std::vector _map;//位置[i][j]在[i*map_SIZE+j]
};

您创建了一个类型,每个实例需要~1MB的堆栈空间,显然比您的堆栈所能容纳的空间要大

  • 可移植选项是从固定数组更改为动态分配或向量类型
  • 非可移植选项是增加应用程序中的堆栈大小(这反过来会增加所有线程的堆栈大小)

您正在堆栈上分配一个360 x 360
平铺对象数组。从一开始这是个坏主意。在堆栈上为您分配了非常大的内存块。堆栈不适用于这种类型的使用

如果您只需要一个实例并预先知道大小,那么这个内存应该是静态的,或者您应该从堆中分配它(使用
new
甚至
malloc()


考虑让
Server
的构造函数使用
new
分配内存,而不是按您的方式分配内存。

默认堆栈大小为1MB。您的结构大小=ushort(2字节)+ulong(4字节)=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 */
这将允许最大映射大小=sqrt(1024*1024/6)=418,因此这允许更大的映射大小,但不是您希望的大小

2-您可以更改visual studio设置,以允许编译器和链接器在堆栈中使用超过1 MB的空间: 您需要将其更改为更大的最大地图大小,即8*10000*10000~800MB

  • 在“项目”上单击鼠标右键,然后从菜单中选择“属性”
  • 转到配置属性->C/C++->命令行,添加此参数:

    /F801000000

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

    /堆栈:801000000

完成了

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