简体   繁体   English

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

[英]C++ Visual Studio stack overflow with 2D array

I'm using Visual Studio 2010 Win 8. I have a class where I'm making a 2D array to hold game data for a game. 我正在使用Visual Studio 2010 Win 8.我有一个类,我正在制作一个2D数组来保存游戏的游戏数据。

Create a blank console app and make main.cpp and add this code. 创建一个空白控制台应用程序并生成main.cpp并添加此代码。 Using 360 for MAP_SIZE causes stack overflow using 359 doesn't. 使用360 for MAP_SIZE导致堆栈溢出使用359不会。 Why would this be? 为什么会这样? I'm looking to have a much larger size array. 我希望有一个更大尺寸的阵列。 I'd like something like 2000 - 10,000 ideally. 我想要像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;
}

My estimates put sizeof(Tile) at 8 or more. 我的估计将sizeof(Tile) 8或更高。 That means sizeof(Server) is at least 360*360*8 = 1036800, which is 0.99 MB. 这意味着sizeof(Server)至少为360 * 360 * 8 = 1036800,即0.99 MB。 The stack is usually small, and 1MB is a common default size. 堆栈通常很小,1MB是常见的默认大小。 You should allocate the tiles on the heap instead, perhaps using std::vector . 你应该在堆上分配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]
};

You're allocating an array of 360 x 360 Tile objects on the stack. 您正在堆栈上分配一个360 x 360 Tile对象的数组。 This is a bad idea from the get go. 从一开始就是一个坏主意。 You are allocated a very large block of memory on the stack. 您在堆栈上分配了一个非常大的内存块。 The stack isn't intended for this type of usage. 堆栈不适用于此类用途。

This memory should either be static, if you only need one instance and know in advance the size, or you should allocate it from the heap (using new or even malloc() ). 如果你只需要一个实例并且事先知道它的大小,那么这个内存应该是静态的,或者你应该从堆中分配它(使用new或甚至malloc() )。

Consider having the constructor for Server allocate the memory using new instead of doing it how you are doing it. 考虑让Server的构造函数使用new分配内存,而不是按照你的方式进行操作。

The stack has limited size. 堆栈的大小有限。 If you need to hold a big array, use dynamic allocation. 如果需要保存大数组,请使用动态分配。

You've created a type which requires ~1MB of stack space per instance, which apparently is larger than your stack can accommodate. 您创建了一个类型,每个实例需要大约1MB的堆栈空间,这显然比您的堆栈可以容纳的大。

  • The portable option is to change from a fixed array to dynamically allocated or to a vector type. 便携式选项是从固定数组更改为动态分配或向量类型。
  • The non-portable option is to increase the stack size in your application (which in turn increases the size of the stack for all threads) 非可移植选项是增加应用程序中的堆栈大小(这反过来会增加所有线程的堆栈大小)

The default stack size is 1MB. 默认堆栈大小为1MB。 your struct size = ushort(2bytes) + ulong (4byte)= 6 bytes which the compiler converts to 8 bytes for struct alignment . 你的struct size = ushort(2bytes)+ ulong(4byte)= 6个字节,编译器将其转换为8个字节以进行结构对齐。 so 8*360*360 =1036800 Bytes , marginally above 1MB 所以8 * 360 * 360 = 1036800字节,略高于1MB

There are 3 solutions: 有3种解决方案:

1- force stop alignment : 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 */

This will allow for a maximum MAP_SIZE= sqrt(1024*1024/6)=418 ,so this allows for a larger mapsize but not the size you wish 这将允许最大MAP_SIZE = sqrt(1024 * 1024/6)= 418,因此这允许更大的地图大小但不允许你想要的大小

2-You can change visual studio settings to allow compiler and linker to use more than 1 MB in stack: you need to change it to be larger the maximum mapsize you need which is 8*10000*10000 ~800MB 2 - 您可以更改visual studio设置以允许编译器和链接器在堆栈中使用超过1 MB:您需要将其更改为您需要的最大地图大小,即8 * 10000 * 10000~800MB

  • right click project, and choose properties from the menu . 右键单击项目,然后从菜单中选择属性。
  • go to configuration properties->C/C++-> Commandline, add this parameter: 转到配置属性 - > C / C ++ - >命令行,添加此参数:

    /F801000000 / F801000000

在此输入图像描述

  • go to Configuration properties->Linker->Commandline, add this parameter 转到配置属性 - >链接器 - >命令行,添加此参数

    /STACK:801000000 / STACK:8.01亿

在此输入图像描述

Done! 完成!

3- the third solution is dynamic array to allocate over the heap, instead of static array , as all have said. 3-第三个解决方案是动态数组,用于分配堆,而不是静态数组,正如所有人所说的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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