IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Erreur de segmentation en allocation automatique d'un tableau 2D de structure


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 40
    Points : 27
    Points
    27
    Par défaut Erreur de segmentation en allocation automatique d'un tableau 2D de structure
    Bonjour,

    J'essaie de créer un programme qui convertit les coordonnées géographiques (longitude, latitude) d'une ellipsoïde (la Terre) prise en photo en coordonnées pixels (colonne, ligne).
    J'utilise entre autre un tableau 2D tab(longitude, latitude) qui contient dans chaque élément une structure 2D(colonne, ligne) ( parce qu'en convertissant une coordonnée géographique (longitude, latitude), on veut obtenir une coordonnée pixel (colonne, ligne) ).
    Mon problème c'est que j'obtiens une erreur lors de l'allocation automatique d'un tableau 2D (pix_coord_tab[nb_lon][nb_lat]), contenant une structure "pixel" (colonne, ligne), si celui-ci devient trop grand :
    Le bug "Erreur de segmentation" apparaît dès que le tableau dépasse 1627 * 1627 éléments.
    Est-ce que je suis obligé de faire une allocation dynamique pour résoudre ce pb. Parce que dans ce cas, je ne vois pas du tout comment faire. Je sais à la limite faire une allocation dynamique d'un tableau 2D d'un type entier ou flottant mais faire l'allocation dynamique d'un tableau 2D (longitude, latitude) contenant une structure (colonne, ligne) est incompréhensible pour moi.

    Je mets, ci-dessous le programme, exécutable, avec essentiellement la partie d'allocation qui crée l'erreur de segmentation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
     
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <new>
    #include <iomanip>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
     
    /* parameters used in the routines as given in Ref. [1] */
    const double  PI         =     3.14159265359;
    const double  SAT_HEIGHT = 42164.0;     /* distance from Earth centre to satellite     */
    const double  R_EQ       =  6378.169;   /* radius from Earth centre to equator         */
    const double  R_POL      =  6356.5838;  /* radius from Earth centre to pol             */
    const double  SUB_LON    =     0.0;     /* longitude of sub-satellite point in radiant */
    const long    CFAC  =  781648343;       /* scaling coefficients (see note above)       */
    const long    LFAC  =  781648343;       /* scaling coefficients (see note above)       */
    const long    COFF  =        1856;      /* scaling coefficients (see note above)       */
    const long    LOFF  =        1856;      /* scaling coefficients (see note above)       */
     
    /* function prototypes */
    int convert(int column, int row, long COFF, long LOFF, double *latitude, double *longitude);//Cette fonction va servir à convertir les coordonnées géographiques en coordonnées pixels avec l'implémentation de fonctions mathématiques prédéfinies
    void deborde();
     
    int main(){
     
      set_new_handler(deborde);
      int col=0, row=0;// (col == c == colonne de la coordonnée pixel); (row == r == l == ligne de la coordonnée pixel)
     
      double lon_min=-81.3, lon_max=81.3, resol=0.09, lat_min, lat_max;//bornes de la grille de coordonnées géographique et résolution de cette grille
      short int nb_lon, nb_lat, i, j;//nombre de longitude, nombre de latitude, incrément i et incrément j
     
      double return_lon=0.0, return_lat=0.0;//valeurs de vérification
      struct pix_coord
      {
        short int c;
        short int r;
      };// Structure correspondant à une coordonnée (colonne, ligne) d'un pixel.
      string nom_fichier("coord_translation.txt");//fichier facultatif de stockage des résultats
     
      nb_lon=(short int)(floor(((lon_max-lon_min) / resol) + double(1.5)));// calcul du nombre de longitudes de la grille de coordonnées géographique
      lat_min=lon_min;
      lat_max=lon_max;
      nb_lat=nb_lon;//nombre de latitudes de la grille de coordonnées géographique
     
      double lon[nb_lon]; //Déclaration automatique d'un tableau 1D de type double
      double lat[nb_lat]; //Déclaration automatique d'un tableau 1D de type double
     
    cout << "Etape 1 : (nb_lon=" << nb_lon << ", nb_lat=" << nb_lat << ")" << endl;
      pix_coord pix_coord_tab[nb_lon][nb_lat]; //Déclaration automatique d'un tableau 2D de structure contenant une coordonnée (colonne, ligne) pour chaque élément du tableau de coordonnées géographiques (longitude, latitude)
     
     
    cout << "Etape 2" << endl;
      short int cpt_colonne_fichier=1;
     
    //Les deux boucles avec incréments i et j servent à construire la grille de coordonnées géographique à partir des bornes lat_min, lat_max, lon_min, lon_max prédéfinies et de la résolution voulue (variable resol). Pour chaque coordonnées géographique (longitude, latitude) de la grille, une coordonnée pixel est calculée avec la fonction convert et stockée dans le tableau 2D de structure pix_coord_tab (où pix_coord_tab[i][j].c == colonne de la coordonnée pixel et pix_coord_tab[i][j].r == ligne de la coordonnée pixel)
      for(i = 0; i < nb_lon; i++)
      {
        lon[i]=lon_min + (resol*i);
        for(j = 0; j < nb_lat; j++)
        {
          lat[j]=lat_min + (resol*j);
    //      convert(lat[j],lon[i],COFF,LOFF,&col,&row);Inutile (phase test déclaration tableaux)
    col=0.0;//test!
    row=0.0;//test!
          pix_coord_tab[i][j].c=col;
          pix_coord_tab[i][j].r=row;
        }
      }
    /*  ofstream fichier(nom_fichier.c_str(), ios::out | ios::trunc);
      if(fichier) // si l'ouverture a réussi
      {
        for(i = 0; i < nb_lon; i++)
        {
          for(j = 0; j < nb_lat; j++)
          {
            fichier << "(" << lon[i] << "," << lat[j] << ")-->(" << pix_coord_tab[i][j].c << "," << pix_coord_tab[i][j].r << ")";
            if(cpt_colonne_fichier == 6)
            {
              fichier << endl;
              cpt_colonne_fichier=1;
            }
            else
            {
              fichier << "\t";
              cpt_colonne_fichier++;
            }
          }
        }
        fichier.close(); // on referme le fichier
      }
      else
      {
        cerr << "Erreur à l'ouverture du fichier " << nom_fichier << endl;
      }
    */
      return (0);
    }
     
    void deborde()
    {
      cerr << "Memoire insuffisante" << endl << "Abandon de l'execution\n" << endl;
      exit (-1);
    }
    L'erreur précise de débug qui s'affiche est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Starting program: /dir/test 
    Etape 1 : (nb_lon=1808, nb_lat=1808)
    
    Program received signal SIGSEGV, Segmentation fault.
    main () at test.cpp:50
    50	cout << "Etape 2" << endl;
    Missing separate debuginfos, use: debuginfo-install glibc-2.9-2.i686 libgcc-4.3.2-7.i386 libstdc++-4.3.2-7.i386
    (gdb) 
    (gdb) bt
    #0  main () at test.cpp:50
    Merci pour votre aide

  2. #2
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Est-ce que je suis obligé de faire une allocation dynamique pour résoudre ce pb
    Oui.

    Pourquoi ?

    Parce que lorsque tu déclares ta variable comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pix_coord pix_coord_tab[nb_lon][nb_lat];
    la variable est allouée "sur la pile" et non pas dans le tas. La pile a une taille relativement limité, c'est la zone mémoire dans laquelle sont allouées toutes les variables locales (ainsi que 2-3 autres trucs).

    Du coup, avec un tableau trop grand, tu explose la pile.

    Avec une allocation dynamique, tu alloues ta variable "sur le tas" et celui-ci correspond, en gros, à la RAM dispo sur le PC (c'est un peu plus complexe, mais c'est l'idée)

    Plus d'infos : http://fr.wikiversity.org/wiki/Langa...ire_en_C.2B.2B

    Pour faire ça avec une allocation dynamique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    pix_coord* pix_coord_tab; // Déclaration d'un pointeur vers des "pix_coord"
    data = new pix_coord[taille_x*taille_y] // Allocation de la mémoire
    ....
    // Pour traiter la valeur présente en x,y :
    pix_coord valeur = pix_coord_tab[x + y*taille_x];
    ....
    // A la fin, faut penser à libérer !!!
    delete pix_coord_tab;

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 40
    Points : 27
    Points
    27
    Par défaut
    Citation Envoyé par buzzkaido Voir le message
    Oui.

    Pourquoi ?

    Parce que lorsque tu déclares ta variable comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pix_coord pix_coord_tab[nb_lon][nb_lat];
    la variable est allouée "sur la pile" et non pas dans le tas. La pile a une taille relativement limité, c'est la zone mémoire dans laquelle sont allouées toutes les variables locales (ainsi que 2-3 autres trucs).

    Du coup, avec un tableau trop grand, tu explose la pile.

    Avec une allocation dynamique, tu alloues ta variable "sur le tas" et celui-ci correspond, en gros, à la RAM dispo sur le PC (c'est un peu plus complexe, mais c'est l'idée)

    Plus d'infos : http://fr.wikiversity.org/wiki/Langa...ire_en_C.2B.2B
    Bonjour,
    Merci beaucoup pour ces explications concernant le fonctionnement sommaire de l'allocation d'espace mémoire. J'aurais bien aimé que l'allocation automatique soit + performant mais ça me pousse vers d'autres connaissances en voyant ça positivement...

    Citation Envoyé par buzzkaido Voir le message
    Pour faire ça avec une allocation dynamique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    pix_coord* pix_coord_tab; // Déclaration d'un pointeur vers des "pix_coord"
    data = new pix_coord[taille_x*taille_y] // Allocation de la mémoire
    ....
    // Pour traiter la valeur présente en x,y :
    pix_coord valeur = pix_coord_tab[x + y*taille_x];
    ....
    // A la fin, faut penser à libérer !!!
    delete pix_coord_tab;
    J'ai pas compris ton code malgré les lignes d'explication, surtout la ligne "data ..." et "pix_coord valeur = ..." parce que je vois pas comment on obtient au final un tableau 2D de structure du type : pix_coord_tab[lon_i][lat_j].c --> valeur colonne de la coordonnée pixel en fonction de la coordonnée 2D géographique (i ème longitude, j ème latitude) et pix_coord_tab[lon_i][lat_j].r --> valeur ligne (ou "row") de la coordonnée pixel en fonction de la coordonnée 2D géographique (i ème longitude, j ème latitude).
    Ceci dit j'ai utilisé des lignes de codes d'un cours sur le net qui explique comment faire une allocation dynamique d'un tableau 2D de type integer et j'ai essayé, au pif, de faire une allocation dynamique d'un tableau 2D de type structure (où la structure représente une coordonnée pixel).
    Mon programme fonctionne mais je n'y comprends rien à la logique de l'allocation.
    Est-ce que tu saurais m'expliquer les 3 lignes que j'ai mis en rouge ci-dessous s'il-te-plait. Parce que cela marche mais je me dis que cela marche peut-être n'importe comment sans que je le sache.
    Merci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <new>
    #include <iomanip>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    
    /* parameters used in the routines as given in Ref. [1] */
    const double  PI         =     3.14159265359;
    const double  SAT_HEIGHT = 42164.0;     /* distance from Earth centre to satellite     */
    const double  R_EQ       =  6378.169;   /* radius from Earth centre to equator         */
    const double  R_POL      =  6356.5838;  /* radius from Earth centre to pol             */
    const double  SUB_LON    =     0.0;     /* longitude of sub-satellite point in radiant */
    const long    CFAC  =  781648343;       /* scaling coefficients (see note above)       */
    const long    LFAC  =  781648343;       /* scaling coefficients (see note above)       */
    const long    COFF  =        1856;      /* scaling coefficients (see note above)       */
    const long    LOFF  =        1856;      /* scaling coefficients (see note above)       */
    
    /* function prototypes */
    int convert(int column, int row, long COFF, long LOFF, double *latitude, double *longitude);//Cette fonction va servir à convertir les coordonnées géographiques en coordonnées pixels avec l'implémentation de fonctions mathématiques prédéfinies
    void deborde();
    
    int main(){
    
      set_new_handler(deborde);
      int col=0, row=0;// (col == c == colonne de la coordonnée pixel); (row == r == l == ligne de la coordonnée pixel)
    
      double lon_min=-81.3, lon_max=81.3, resol=0.09, lat_min, lat_max;//bornes de la grille de coordonnées géographique et résolution de cette grille
      short int nb_lon, nb_lat, i, j;//nombre de longitude, nombre de latitude, incrément i et incrément j
    
      double return_lon=0.0, return_lat=0.0;//valeurs de vérification
      struct pix_coord
      {
        short int c;
        short int r;
      };// Structure correspondant à une coordonnée (colonne, ligne) d'un pixel.
      string nom_fichier("coord_translation.txt");//fichier facultatif de stockage des résultats
    
      nb_lon=(short int)(floor(((lon_max-lon_min) / resol) + double(1.5)));// calcul du nombre de longitudes de la grille de coordonnées géographique
      lat_min=lon_min;
      lat_max=lon_max;
      nb_lat=nb_lon;//nombre de latitudes de la grille de coordonnées géographique
    
      double *lon= new double [nb_lon]; //Déclaration dynamique du tableau 1D des longitudes de type double
      double *lat = new double [nb_lat]; //Déclaration dynamique du tableau 1D des latitudes de type double
    
    cout << "Etape 1 : (nb_lon=" << nb_lon << ", nb_lat=" << nb_lat << ")" << endl;
      pix_coord **pix_coord_tab = new pix_coord* [nb_lon]; //Déclaration dynamique d'un tableau 2D de structure contenant une coordonnée (colonne, ligne) pour chaque élément du tableau de coordonnées géographiques (longitude, latitude)
      for (int i = 0; i < nb_lon; i++) // Initialisation des pointeurs du premier niveau (chaque pix_coord_tab[i]) à 0 pour éviter un bug si mauvais delete c-a-d delete sur un pointeur quelconque non nul. i = incrément des éléments "longitudes"
        pix_coord_tab[i] = 0;
      for (int i = 0; i < nb_lon; i++)
        pix_coord_tab[i] = new pix_coord[nb_lat];
    
    cout << "Etape 2" << endl;
      short int cpt_colonne_fichier=1;
    
    //Les deux boucles avec incréments i et j servent à construire la grille de coordonnées géographique à partir des bornes lat_min, lat_max, lon_min, lon_max prédéfinies et de la résolution voulue (variable resol). Pour chaque coordonnées géographique (longitude, latitude) de la grille, une coordonnée pixel est calculée avec la fonction convert et stockée dans le tableau 2D de structure pix_coord_tab (où pix_coord_tab[i][j].c == colonne de la coordonnée pixel et pix_coord_tab[i][j].r == ligne de la coordonnée pixel)
      for(i = 0; i < nb_lon; i++)
      {
        lon[i]=lon_min + (resol*i);
        for(j = 0; j < nb_lat; j++)
        {
          lat[j]=lat_min + (resol*j);
    //      convert(lat[j],lon[i],COFF,LOFF,&col,&row);Fonction inutile pour l'instant c-a-d pendant la phase de test de déclaration dynamique des tableaux.
    col=0.0;//test!
    row=0.0;//test!
          pix_coord_tab[i][j].c=col;
          pix_coord_tab[i][j].r=row;
        }
      }
    
    /*
      ofstream fichier(nom_fichier.c_str(), ios::out | ios::trunc);
      if(fichier) // si l'ouverture a réussi
      {
        for(i = 0; i < nb_lon; i++)
        {
          for(j = 0; j < nb_lat; j++)
          {
            fichier << "(" << lon[i] << "," << lat[j] << ")-->(" << pix_coord_tab[i][j].c << "," << pix_coord_tab[i][j].r << ")";
            if(cpt_colonne_fichier == 6)
            {
              fichier << endl;
              cpt_colonne_fichier=1;
            }
            else
            {
              fichier << "\t";
              cpt_colonne_fichier++;
            }
          }
        }
        fichier.close(); // on referme le fichier
      }
      else
      {
        cerr << "Erreur à l'ouverture du fichier " << nom_fichier << endl;
      }
    */
    
      delete [] lon;
      delete [] lat;
      for (int i = 0; i < nb_lon; i++)
        delete [] pix_coord_tab[i];
      delete [] pix_coord_tab;
    
      return (0);
    }
    
    void deborde()
    {
      cerr << "Memoire insuffisante" << endl << "Abandon de l'execution\n" << endl;
      exit (-1);
    }

  4. #4
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    surtout la ligne "data ..." et "pix_coord valeur = ..."
    C'est normal, faute de frappe...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    pix_coord* pix_coord_tab; // Déclaration d'un pointeur vers des "pix_coord"
    pix_coord_tab = new pix_coord[taille_x*taille_y] // Allocation de la mémoire
    ....
    // Pour traiter la valeur présente en x,y :
    pix_coord valeur = pix_coord_tab[x + y*taille_x];
    ....
    // A la fin, faut penser à libérer !!!
    delete pix_coord_tab;

    Dans ton code, en fait :

    pix_coord **pix_coord_tab = new pix_coord* [nb_lon];

    => là tu crée un tableau de pointeurs

    for (int i = 0; i < nb_lon; i++)
    pix_coord_tab[i] = new pix_coord[nb_lat];

    => là, pour chaque pointeur du tableau créé précédemment, tu crée un tableau de données "pix_coord"

    C'est franchement plus lourd à crééer / détruire, et tu n'a pas les données alignées... je te déconseille cette méthode.

    Je t'explique mieux le code que j'en envoyé :

    Par exemple, tu veux créer un tableau 2D de 3*4 = 12 éléments (de 0 à 11) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    -------------------------
    |  0  |  1  |  2  |  3  |
    -------------------------
    |  4  |  5  |  6  |  7  |
    -------------------------
    |  8  |  9  |  10 |  11 |
    -------------------------

    Ce qu'on va faire, c'est créer un tableau à 1 dimension qui contient 12 éléments :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ------------------------------------------------------------------------
    |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |  10 | 11 |
    ------------------------------------------------------------------------

    Là tu vois bien que ton tableau 2D rentre dedans, il y a autant d'éléments. Le reste, c'est juste un problème d'organisation.

    Maintenant, pour t'y retrouver avec tes coordonnées 2D dans le tableau :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
          x=0    x=1   x=2   x=3
     
         ------------------------
    y=0  |  0  |  1  |  2  |  3  |
         ------------------------
    y=1  |  4  |  5  |  6  |  7  |
         ------------------------
    y=2  |  8  |  9  |  10 | 11  |
         ------------------------
    Tu remarqueras que par exemple, la case en x=2 et y=1 porte l'indice n°6

    Et tu remarqueras que tu peux faire :

    indice = largeur_du_tableau * y + x

    La méthode que je te propose est d'allouer un tableau 1-dimension de la bonne taille, et ensuite, quand tu veux accéder à la case (x,y) il te suffit de calculer son indice.

    C'est bien mieux : une seule allocation mémoire, toutes les données sont à la suite, et surtout c'est beaucoup plus courant comme ça car ça te permet aussi de faire des tableaux 3D, 4D, 5D... tout aussi facilement, seule la fonction de calcul de l'indice est modifiée.

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Citation Envoyé par buzzkaido Voir le message
    La méthode que je te propose est d'allouer un tableau 1-dimension de la bonne taille, et ensuite, quand tu veux accéder à la case (x,y) il te suffit de calculer son indice.
    J'ai pas tout lu mais effectivement quand le nombre de colonne est le même pour chaque ligne, c'est une option intéressante. Ca permet aussi alors d'utiliser std::vector (ou tr1/boost/std(C++0x)::array) et d'avoir l'impression d'une variable automatique sans se soucier de l'allocation.

    @alter : en théorie tu peux régler les paramètres de ton compilo pour augmenter la taille de la pile, mais je pense que c'est de toute façon une mauvaise idée pour autant de données.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 40
    Points : 27
    Points
    27
    Par défaut
    Citation Envoyé par buzzkaido Voir le message
    La méthode que je te propose est d'allouer un tableau 1-dimension de la bonne taille, et ensuite, quand tu veux accéder à la case (x,y) il te suffit de calculer son indice.

    C'est bien mieux : une seule allocation mémoire, toutes les données sont à la suite, et surtout c'est beaucoup plus courant comme ça car ça te permet aussi de faire des tableaux 3D, 4D, 5D... tout aussi facilement, seule la fonction de calcul de l'indice est modifiée.
    Merci buzzkaido pour toute l'aide et cette autre solution très intéressante d'allocation que je vais essayer d'appliquer dans la journée.

    Citation Envoyé par 3DArchi Voir le message
    @alter : en théorie tu peux régler les paramètres de ton compilo pour augmenter la taille de la pile, mais je pense que c'est de toute façon une mauvaise idée pour autant de données.
    Merci pour cette information. C'est bon à savoir même si, comme tu le conseilles, j'éviterais de l'utiliser.

    Citation Envoyé par 3DArchi Voir le message
    Ca permet aussi alors d'utiliser std::vector (ou tr1/boost/std(C++0x)::array) et d'avoir l'impression d'une variable automatique sans se soucier de l'allocation.
    Là j'ai pas compris ce que tu entends par "avoir l'impression d'une variable automatique" avec vector.

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Citation Envoyé par alter Voir le message
    Là j'ai pas compris ce que tu entends par "avoir l'impression d'une variable automatique" avec vector.
    Tu délègues toute la cuisine d'allocation/libération au type std::vector. Dans ton code, tu fais juste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void ma_fonction()
    {
       // tableau automatique à la 'C' :
       int mon_tableau[2500];// détruit en sortie de portée ~ 'automatique'
       // avec un vecteur :
       std::vector<int> mon_vect(2500);// détruit en sortie de portée ~ 'automatique'
    }
    Tu n'as pas besoin de faire de new/delete. Le tableau est alloué à sa définition et libéré à la sortie de porté. Il se comporte comme une variable automatique.

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 40
    Points : 27
    Points
    27
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Salut,

    Tu délègues toute la cuisine d'allocation/libération au type std::vector. Dans ton code, tu fais juste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void ma_fonction()
    {
       // tableau automatique à la 'C' :
       int mon_tableau[2500];// détruit en sortie de portée ~ 'automatique'
       // avec un vecteur :
       std::vector<int> mon_vect(2500);// détruit en sortie de portée ~ 'automatique'
    }
    Tu n'as pas besoin de faire de new/delete. Le tableau est alloué à sa définition et libéré à la sortie de porté. Il se comporte comme une variable automatique.
    D'accord, je comprends. Je ferais des tests de cette solution aussi.

    MERCI A TOUS LES 2 ! Bonne journée !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreur de segmentation allocation dynamique
    Par baguiwoopy dans le forum C
    Réponses: 8
    Dernier message: 28/04/2012, 21h48
  2. Erreur de segmentation
    Par Trunks dans le forum C
    Réponses: 3
    Dernier message: 06/10/2005, 18h28
  3. Erreur de segmentation (Inconnue)
    Par Dark-Meteor dans le forum C
    Réponses: 5
    Dernier message: 08/09/2005, 13h42
  4. [Dev-C++] Erreur de segmentation...
    Par sas dans le forum Dev-C++
    Réponses: 11
    Dernier message: 26/03/2005, 14h25
  5. erreur de segmentation
    Par transistor49 dans le forum C++
    Réponses: 10
    Dernier message: 15/03/2005, 11h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo