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 :

Double pointeur et realloc


Sujet :

C

  1. #1
    Membre averti
    Inscrit en
    Juin 2008
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 63
    Par défaut Double pointeur et realloc
    Bonjour, dans le cadre d'un projet je suis amené à travailler sur des matrices ( double pointeur) que je veux modifier.

    Par exemple,
    J'ai la matrice matContr suivante:

    1 1 0 0 0 0
    1 -1 0 0 0 127
    1 0 1 0 0 0
    1 0 -1 0 0 63
    1 0 0 1 0 0
    1 0 0 -1 0 0
    1 0 0 0 1 0
    1 0 0 0 -1 0

    Nombre de ligne = NC et nombre de colonne = ND.
    Sur cette matrice, je garde toujours la premiere et la dernier colonne et sur les colonnes qui restent, je veux pouvoir en choisir 3 consécutives (indice = colonne de départ -1).

    Mon code qui est le suivant :
    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
    int ligne = 0;
      int colonne = 0 ;
      int NbRows = NC + 1;
     
     
      for(int i=0;i<NC;i++)
      {
          colonne=0;
            for(int j=0;j<ND;j++)
            {
              //On ne prend en compte que les dimensions voulues ainsi que la colonne des constantes
              if(j==0 || (j>indice && j<(indice+4)) || j>(ND-2) )
              {
                matContr[ligne][colonne]=matContr[i][j];
                colonne++;
              }
            }
            ligne++;
          }
    Jusque là pas de problème, à cette nouvelle matrice , j'aimerais lui rajouter une ligne ( par exemple avec que des 0).
    Il faut donc que je réallouer l'espace suffisant ( NC+1 ) mais j'ai une erreur de segmentation que je ne comprend pas.


    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
      matContr = (int**)realloc(matContr, sizeof(int*) * NbRows);
     
      for(int i=0;i<NC;i++)
      {
          colonne=0;
            for(int j=0;j<ND;j++)
            {
              //On ne prend en compte que les dimensions voulues ainsi que la colonne des constantes
              if(j==0 || (j>indice && j<(indice+4)) || j>(ND-2) )
              {
                matContr[ligne][colonne]=matContr[i][j];
                colonne++;
              }
            }
            ligne++;
          }
     
      //Nouvelle ligne
      for(int k=0;k<ND:k++)
      {
        matContr[NC][k]=0;
      }
    Voyez vous le problème?

  2. #2
    Membre averti
    Inscrit en
    Juin 2008
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 63
    Par défaut re
    Le ":" dans le for n'en est pas la cause, c'est juste une erreur de saisie de ma part...

  3. #3
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Lors de la réallocation, vous n'allouez qu'une colonne de pointeur sur int. Les lignes ne sont pas allouées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    matContr = (int**)realloc(matContr, sizeof(int*) * NbRows);
    for(...){
      matContr[i] = realloc(matContr[i], NBLines * sizeof(*matContr[i]));
    }
    Pouvez vous montrer comment est allouée la première matrice ?

    PS: le cast est déconseillé avant le realloc.
    Il faut bien sur vérifier le retour de realloc.

  4. #4
    Membre chevronné Avatar de KindPlayer
    Profil pro
    Inscrit en
    Février 2007
    Messages
    471
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 471
    Par défaut
    je ne suis pas sur que tu puisses faire juste un realloc global comme ça. A mon avis il faut egalement reallouer chaque ligne individuellement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for (i = 0; i < ND; i++){
     matctr[i] = (int*)realloc(matCtr[i],(ND+1)*sizeof(int));
     
    }
    Mais je ne suis pas sur. A tester.
    [EDIT] Il faut incrementer le pointeur *matctr aussi.
    [EDIT2] Plus simple avec l'operateur []
    [EDIT3] Oublié qu'avec realloc faut reallouer la taille totale

  5. #5
    Membre averti
    Inscrit en
    Juin 2008
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 63
    Par défaut re
    Je m'en suis rendu compte, et j'ai donc fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      matContr = (int**)realloc(matContr, sizeof(int*) * NbRows);
      for(int h=0;h<NbRows;h++)
      {
        matContr[h] = (int*)realloc(matContr[h], sizeof(int) * ND);
      }
    ...
    Le problème est toujours là...l'erreur se segmentation a apparament changer...quand je lance valgrind, pas d'erreur de segmentation...??? sinon en compilant normalement, j'ai cette erreur...peut être est-ce une fuite mémoire qui provoquerait un comportement aléatoire je sais pas...

    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
      int ligne = 0;
      int colonne = 0 ;
      int NbRows = NC + 1;
     
      matContr = (int**)realloc(matContr, sizeof(int*) * NbRows);
      for(int h=0;h<NbRows;h++)
      {
        matContr[h] = (int*)realloc(matContr[h], sizeof(int) * ND);
      }
     
      for(int i=0;i<NC;i++)
      {
          colonne=0;
            for(int j=0;j<ND;j++)
            {
              //On ne prend en compte que les dimensions voulues ainsi que la colonne des constantes
              if(j==0 || (j>indice && j<(indice+4)) || j>(ND-2) )
              {
                matContr[ligne][colonne]=matContr[i][j];
                matLoop[ligne][colonne]=matContr[i][j];
                //printf("contrainte matContr[%d][%d]=%d\n",ligne,colonne,matContr[i][j]);
                colonne++;
              }
            }
            ligne++;
          }
     
     
     
     printf("init Matrix dim N : après \n");
      for(int i=0;i<NC; i++)
        for(int j=0; j<ND; j++){
          printf("%d\t",matContr[i][j]);
          if(j==(ND-1)) printf("\n");
        }
    Dans l'exemple ci-dessus, j'ai pas initialisé les valeurs de ma ligne supplémentaire, mais cela devrait tout de même marcher , non?

  6. #6
    Invité(e)
    Invité(e)
    Par défaut
    Attention à l'utilisation de realloc.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    matContr = (int**)realloc(matContr, sizeof(int*) * NbRows);
    for(int h=0;h<NbRows;h++) {
       matContr[h] = (int*)realloc(matContr[h], sizeof(int) * ND);
    }
    Ce code présente plusieurs problèmes :

    Si la valeur de matContr change après l'appel à realloc, les realloc suivant pointeront n'importe où... et en plus la mémoire précédement appelée sera perdue.

    Si la valeur de matContr reste la même, on réalise un realloc sur les lignes déjà existantes, pas de problème, mais on appelle aussi realloc sur des lignes qui n'ont jamais été allouées (les nouvelles).

    Le plus simple à mon avis est de d'allouer un nouvelle matrice plus grande que le première, y sauvegarder les données communes, supprimer la première matrice.

  7. #7
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Lorsque tu fais un realloc sur matContr, la valeur de matContr est susceptible de changer (et même de passer à NULL en cas d'échec de réallocation, cas que tu devrais tester).
    Par contre (si matContr ne passe pas à NULL) le contenu est inchangé, mis à part les cases que tu as ajoutées qui contiennent, elles, n'importe quoi. Il n'est donc pas nécessaire de modifier la partie antérieure au realloc de la matrice.

    Par contre, pour le pointeur ajouté, il faut allouer une nouvelle ligne.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    matContr = (int**)realloc(matContr, sizeof(int*) * NbRows);
    for(int h=0;h<NbRows;h++)
    {
    matContr[h] = (int*)realloc(matContr[h], sizeof(int) * ND);
    }
    Ce code ne marche pas parce que matContr[NbRows-1], le nouveau pointeur, contient n'importe quoi. Il aurait fallu l'initialiser au préalable à NULL pour que le realloc se comporte comme un simple malloc.
    De toute façon, la reallocation des autres pointeurs est inutile, et il doit suffire de faire (en omettant les tests sur les allocations )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    matContr = realloc(matContr, sizeof(int*) * NbRows);
    matContr[NbRows-1] = malloc(sizeof(int) * ND);

Discussions similaires

  1. Double pointeurs dans les listes chainées
    Par NouK32 dans le forum Débuter
    Réponses: 8
    Dernier message: 10/02/2008, 18h19
  2. double pointeur dans un fichier txt
    Par micka180 dans le forum VBScript
    Réponses: 14
    Dernier message: 22/01/2008, 16h23
  3. Réponses: 6
    Dernier message: 07/07/2007, 18h12
  4. Réponses: 6
    Dernier message: 04/01/2007, 01h30
  5. double pointeur?
    Par ostralo dans le forum C++
    Réponses: 17
    Dernier message: 23/02/2006, 18h24

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