9

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.

Create a blank console app and make main.cpp and add this code. Using 360 for MAP_SIZE causes stack overflow using 359 doesn't. Why would this be? I'm looking to have a much larger size array. I'd like something like 2000 - 10,000 ideally.

#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 Answers 5

8

My estimates put sizeof(Tile) at 8 or more. That means sizeof(Server) is at least 360*360*8 = 1036800, which is 0.99 MB. The stack is usually small, and 1MB is a common default size. You should allocate the tiles on the heap instead, perhaps using 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]
};
Sign up to request clarification or add additional context in comments.

Comments

5

You're allocating an array of 360 x 360 Tile objects on the stack. 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()).

Consider having the constructor for Server allocate the memory using new instead of doing it how you are doing it.

Comments

4

The stack has limited size. If you need to hold a big array, use dynamic allocation.

Comments

4

You've created a type which requires ~1MB of stack space per instance, which apparently is larger than your stack can accommodate.

  • 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)

Comments

0

The default stack size is 1MB. your struct size = ushort(2bytes) + ulong (4byte)= 6 bytes which the compiler converts to 8 bytes for struct alignment . so 8*360*360 =1036800 Bytes , marginally above 1MB

There are 3 solutions:

1- force stop alignment :

 #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

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

  • right click project, and choose properties from the menu .
  • go to configuration properties->C/C++-> Commandline, add this parameter:

    /F801000000

enter image description here

  • go to Configuration properties->Linker->Commandline, add this parameter

    /STACK:801000000

enter image description here

Done!

3- the third solution is dynamic array to allocate over the heap, instead of static array , as all have said.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.