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 :

besoin d'eclaircissement sur malloc et free


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 48
    Par défaut besoin d'eclaircissement sur malloc et free
    Bonjour à tous

    Je pédale un peu dans la semoule avec ces 2 fonctions là ...
    Après quelques recherches pour avoir des exemples je suis tombé la dessus :

    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
    /* illustration of dynamically allocated 2D array */
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
      int i; /* general purpose variable used for loop index */
      int j; /* general purpose variable used for loop index */
     
      int **a;     /* this is the array name */
      int size_x; /* this variable will be used for the first  dimension */
      int size_y; /* this variable will be used for the second dimension */
     
      /* suppose we want an array of int: a[5][3] */
      size_x = 5;
      size_y = 3;
     
      /*  allocate storage for an array of pointers */
      a = malloc(size_x * sizeof(int *));
     
      /* for each pointer, allocate storage for an array of ints */
      for (i = 0; i < size_x; i++) {
        a[i] = malloc(size_y * sizeof(int));
      }
     
      /* just for kicks, show the addresses (note: not all sequential) */
      /* assign an arbitrary value to each element        */
      for (i = 0; i < size_x; i++) {
        for (j = 0; j < size_y; j++) {
          printf("&a[%d][%d] = %p\n", i, j, &a[i][j]); /* show the addresses */
          a[i][j] = i * size_y + j; /* just some unique number for each element */
        }
        printf ("\n");
      }
     
      /* now show the contents that were assigned */
      for (i = 0; i < size_x; i++) {
        for (j = 0; j < size_y; j++) {
          printf("a[%d][%d] = %2d\n", i, j, a[i][j]);
        }
        printf ("\n");
      }
     
      /* now for each pointer, free its array of ints */
      for (i = 0; i < size_y; i++) {
        free(a[i]);
      }
      /* now free the array of pointers */
      free(a);
     
      return 0;
    }
    Si j'ai bien compris, on crée d'abord une variable **a, en gros un pointeur sur les colonnes qui pointe sur les lignes. Puis on attribut le nombre de colonnes en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    a = malloc(size_x * sizeof(int *));
    Et on défini le nombre de lignes en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      for (i = 0; i < size_x; i++) {
        a[i] = malloc(size_y * sizeof(int));
      }
    On a donc un tableau contenant size_x colonnes, qui contiennent size_y lignes.

    Jusque là je crois que c'est bon, c'est après que ça se complique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      for (i = 0; i < size_y; i++) {
        free(a[i]);
      }
    Si je comprends bien on va libérer les lignes crée avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (i = 0; i < size_x; i++) {
        a[i] = malloc(size_y * sizeof(int));
      }
    Mais alors pourquoi il utilise size_y pour libérer les a[i] alors que le malloc était avec size_x ?

    Je suis donc un peu embrouiller avec la libération, car selon moi il aurait fallu faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      for (i = 0; i < size_x; i++) {
        free(a[i]);
      }

  2. #2
    Inactif  
    Homme Profil pro
    Inscrit en
    Septembre 2003
    Messages
    570
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Septembre 2003
    Messages : 570
    Par défaut
    je pense que tu as raison, c'est peut etre une erreur du clavier, sinon est ce que le programme ne represente aucune erreurs?

    (que size_x soit le nombre de lignes et size_y celui des colonnes ou l'inverse reste conventionnel)

  3. #3
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 48
    Par défaut
    merci pour la réponse. J'ai fais un bout de code juste pour tester malloc et free :

    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
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
      int i = 0, x = 5, y = 10;
      int **tableau2D = NULL;
     
      tableau2D = malloc((x) * sizeof(int*));
     
      for(i = 0 ; i < x ; i++)
      {
        tableau2D[i] = malloc((y) * sizeof(int));
      }
     
      for(i = 0 ; i < x ; i++)
      {
        free(tableau2D[i]);
      }
      free(tableau2D);
    }
    j'ai essayé avec plusieurs valeurs pour x et y, il ne fais pas d'erreur de segmentation ou autre, il doit donc être correcte.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Mais alors pourquoi il utilise size_y pour libérer les a[i] alors que le malloc était avec size_x ?
    Pour (au choix) crasher le programme ou créer des fuites de mémoire.
    Non, sérieusement, si on alloue dynamiquement size_x zones mémoire de size_y objets de type quelconque, il faut bien sûr déallouer de la même manière.

    Dans ton code, tu devrais toutefois rajouter des tests pour vérifier si tes malloc retournent bien une valeur non NULL. Car si un des malloc renvoie NULL, que tu ne vérifies pas, puis que tu accèdes à cette adresse, le programme va inévitablement crasher. Le programme écrit tel quel présente donc un bug, susceptible de provoquer un crash, même si cela a très peu de chance d'arriver. (Ca doit arriver très rarement qu'un malloc retourne NULL sur une machine lambda)

  5. #5
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 48
    Par défaut
    Ok merci pour le conseil, donc juste rajouter un truc du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    tableau2D = malloc((x) * sizeof(int*));
     
    if(tableau2D[i] == NULL)
    {return 0;}
    Je vais essayer, parce que j'ai repris le petit code d'avant pour en faire quelque chose d'utile, mais j'ai une erreur de segmentation au moment de la libération mémoire. Le plus bizarre c'est que si je retire la fonction qui intervient sur le tableau, l'erreur de segmentation disparait et pourtant après vérification cette erreur de segmentation arrive après la fonction.

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Ok merci pour le conseil, donc juste rajouter un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    tableau2D = malloc((x) * sizeof(int*));
     
    if(tableau2D[i] == NULL)
    {return 0;}
    Pour le premier test : il faut tester tableau2D (pointeur de pointeur sur int) et non tableau2D[ i ], qui serait ici la valeur pointée (pointeur sur int) dans le premier élément du tableau (car dans ton code, i vaut initialement 0).

    Pour les autres tests, il faut tester aussi chaque retour de malloc dans la boucle (tableau2D[ i ]).

    Je vais essayer, parce que j'ai repris le petit code d'avant pour en faire quelque chose d'utile, mais j'ai une erreur de segmentation au moment de la libération mémoire. Le plus bizarre c'est que si je retire la fonction qui intervient sur le tableau, l'erreur de segmentation disparait et pourtant après vérification cette erreur de segmentation arrive après la fonction.
    Il faut nous montrer ton code modifié.

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

Discussions similaires

  1. Besoin d'eclaircissements sur Qlikview
    Par diabbs dans le forum QlikView
    Réponses: 0
    Dernier message: 08/04/2013, 00h35
  2. Besoin d'eclaircissement sur la MMU
    Par Odulo dans le forum Linux
    Réponses: 1
    Dernier message: 22/11/2010, 08h52
  3. besoin de comprehension sur free() et pointeur
    Par leprofmelo dans le forum C
    Réponses: 44
    Dernier message: 22/11/2007, 10h22
  4. Besoin d'eclaircissement sur la persistence
    Par willoi dans le forum Hibernate
    Réponses: 2
    Dernier message: 26/06/2007, 18h01
  5. besoins d'eclaircissements sur les dossiers cron.*
    Par rhaamo dans le forum Administration système
    Réponses: 5
    Dernier message: 23/02/2007, 11h38

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