2012-12-20 13 views
8

Utilizzo Visual Studio 2010 Win 8. Ho una classe in cui sto creando un array 2D per contenere i dati di gioco per un gioco.Overflow di stack di Visual Studio C++ con array 2D

Creare un'app console vuota e creare main.cpp e aggiungere questo codice. L'utilizzo di 360 per MAP_SIZE causa l'overflow dello stack utilizzando 359 no. Perché dovrebbe essere? Sto cercando di avere una matrice di dimensioni molto più grande. Mi piacerebbe qualcosa come 2000 - 10.000 idealmente.

#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; 
} 

risposta

8

Le mie stime mettono sizeof(Tile) a 8 o più. Ciò significa che sizeof(Server) è almeno 360 * 360 * 8 = 1036800, ovvero 0,99 MB. Lo stack è in genere piccolo e 1 MB è una dimensione predefinita comune. Dovresti invece allocare le tessere nell'heap, magari usando 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] 
}; 
4

La pila ha dimensioni limitate. Se hai bisogno di tenere un grande array, usa l'allocazione dinamica.

4

Hai creato un tipo che richiede ~ 1 MB di spazio di stack per istanza, che apparentemente è più grande di quello che può contenere lo stack.

  • L'opzione portatile è quella di passare da una matrice fissa a allocata dinamicamente oa un tipo di vettore.
  • L'opzione non portabile è quello di aumentare la dimensione di stack nell'applicazione (che a sua volta aumenta la dimensione dello stack per tutti i thread)
5

stai allocare una matrice di 360 x 360 Tile oggetti lo stack. Questa è una cattiva idea fin dall'inizio. Ti viene assegnato un grande blocco di memoria in pila. Lo stack non è inteso per questo tipo di utilizzo.

Questa memoria deve essere statica, se è necessaria solo un'istanza e conoscere in anticipo la dimensione, oppure è necessario allocarla dall'heap (utilizzando new o anche malloc()).

Considerare di avere il costruttore per Server allocare la memoria utilizzando new invece di farlo come si sta facendo.

0

La dimensione dello stack predefinita è 1 MB. la tua struct size = ushort (2bytes) + ulong (4byte) = 6 byte che il compilatore converte in 8 byte per l'allineamento di struct. così 8 * 360 * 360 = 1036800 Bytes, marginalmente sopra 1MB

Ci sono 3 soluzioni:

1- forza allineamento fermata:

#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 */ 

Ciò consentirà un massimo MAP_SIZE = sqrt (1024 * 1024/6) = 418, quindi questo consente una mappatura più grande ma non la dimensione desiderata

2-È possibile modificare le impostazioni dello studio visivo per consentire al compilatore e al linker di utilizzare più di 1 MB nello stack: si bisogno di cambiarlo in maggiore è la dimensione massima di cui hai bisogno che è 8 * 10000 * 10000 ~ 800MB

  • tasto destro del mouse sul progetto e scegliere Proprietà dal menu.
  • passare a Configurazione proprietà-> C/C++ -> Riga di comando, aggiungere questo parametro:

    /F801000000

enter image description here

  • andare a Configurazione proprietà-> Linker- > Commandline, aggiungi questo parametro

    /STACK: 801000000

Fatto!

3- la terza soluzione è l'array dinamico da allocare sull'heap, invece dell'array statico, come tutti hanno detto.