繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM