2009-03-12 6 views
0

J'essaye d'allouer une grande matrice 4D mais je veux le faire dynamiquement. Quand je crée simplement la matrice statique, tout fonctionne bien, donc je sais que j'ai suffisamment de mémoire pour l'instant. Cependant, quand j'essaie de mettre en œuvre dynamiquement la même chose, ça casse chaque fois que j'entre dans la troisième dimension et je dois en arriver à une quatrième! Quelqu'un peut-il me dire pourquoi ce code ne fonctionne pas?Pourquoi ai-je une erreur de segmentation (core dumped) lorsque j'essaie d'allouer une matrice 4D?

#include <iostream> 

using namespace std; 

static const int time1 = 7; 
static const int tlat = 15; 
static const int tlon = 17; 
static const int outlev = 3; 

int main(void) 
{ 
    //allocate four dimensional dataIn 
    int ****dataIn; 
    dataIn = new int ***[time1]; 
    if (dataIn == NULL) { return 1; } 

    for(int i = 0 ; i < time1 ; i++) { 
     dataIn[i] = new int **[tlat]; 
     if (dataIn[i] == NULL) { return 1; } 

     for(int j = 0 ; j < tlat ; j++) { 
      dataIn[i][j] = new int *[tlon]; 
      if (dataIn[i][j] == NULL) { return 1; } 

      for(int k = 0 ; k < tlon ; k++) { 
       dataIn[i][j][k] = new int[outlev]; 
       if (dataIn[i][j][k] == NULL) { return 1; } 
      } 
     } 
    } 
    //there is more code that happens here to add values to dataIn 
    //and eventually output it but I know all of that works   
    return 0; 
} 

J'ai essayé beaucoup de différentes variations sur ce code, et même utilisé malloc au lieu de nouveau, mais je ne peux pas le faire fonctionner. Toute aide est la bienvenue.

+0

Ne plante pas ici. Peut-être que le bloc de code * réel * va vous aider. – dirkgently

+0

J'ai compilé le code que vous avez publié et il s'est exécuté sans se bloquer dans VS2005. Veuillez être plus précis quant à votre problème. –

+0

Dans un commentaire ci-dessous, vous indiquez que l'erreur est sur la ligne: 'dataIn [i] [j] ='. Quelles sont les valeurs de i et j. Quelle est la valeur du pointeur retourné, etc Si vous n'avez pas de debuger (difficile à grok) alors vous pouvez le faire à l'ancienne en mettant des instructions d'impression qui montrent l'état. –

Répondre

2

Avez-vous exécuté ceci dans un débogueur? À mon avis, le code semble bien, mais un débogueur vous dira où il se bloque, ce qui peut suffire à vous aider à le résoudre.

+0

Le code compile bien, et à part mon compilateur je n'ai pas de débogueur. En raison de tout mon propre débogage, juste en essayant tant de choses, je sais qu'il casse sur la ligne qui essaie d'allouer dataIn [i] [j]. Pour quelque raison que ce pointeur est probablement mauvais, mais je ne sais pas pourquoi ou comment le réparer. –

+0

err, quelle plate-forme êtes-vous sur tel que vous n'avez pas de débogueur? – olliej

+0

un débogueur va changer votre vie – tarn

2

Vous devriez probablement allouer toute la mémoire dans un tableau plat, puis calculer les indices toi même. Envelopper le tout dans un objet pour l'encapsulation.

class Matrix { 
private: 
     int* data;   
     int[] sizes; 
     int nDimensions; 

public: 
     // allocates the data pointer and copies the other parameters 
     Matrix(int[] sizes, int nDimensions); 

     // frees the data and sizes arrays 
     ~Matrix(); 

     // calculates the cell position and returns it 
     int getCell(int[] coordinates); 

     // calcultes the cell position and sets its value 
     void setCell(int[] coordinates, int value); 

private: 
     // used by getCell and setCell, calculates the cell's 
     // location in the data array 
     size_t calculateCellPosition(int[] coordinates); 
}; 
+0

Cette approche vous donnera aussi l'avantage d'être plus rapide. Bien que toutes les situations ne nécessitent pas un code rapide, il est toujours une bonne habitude à prendre. – Thomas

1

Il compile et fonctionne correctement sur ma machine Linux. BTW, avec C++ standard, lancerait une exception std :: bad_alloc (au lieu de renvoyer NULL) quand il est incapable d'allouer la mémoire. Il peut donc être intéressant d'attraper cette exception au lieu de tester un pointeur NULL.

0

Comme souligné par cmeerw, un test sur NULL ou 0 n'est pas nécessaire dans std-C++.

Il serait utile si vous pouviez ajouter un commentaire à l'endroit exact où vous obtenez un segv.

En outre: Quel compilateur utilisez-vous et sur quel système d'exploitation?

0

Check out boost::multiarray, il fait exactement ce que vous voulez, sauf plus efficacement en ne faisant qu'une seule allocation de tas.

Questions connexes