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 d'allocation dynamique


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Inscrit en
    Avril 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2012
    Messages : 12
    Par défaut erreur d'allocation dynamique
    Bonsoir,

    j'ai un gros problème, ça fait plusieurs heures que je tente diverse approche à mon problème mais pas moyen de le régler ni même ne serrait-ce que le comprendre ...

    Alors voilà, je dois faire un programme et dedans j'ai besoin d'allouer de la mémoire a un tableau [x][y] donc, je crée la fonction dans le int main premièrement, et tout fonctionne parfaitement .. Après je me dis que ce serrait plus pratique de mettre cet algorithme dans une fonction à part pour pouvoir le réutiliser, malheureusement c'est là que le problème apparaît ... Le programme ne fonctionne plus avec l'algorithme dans une fonction que le main.

    Voilà le code pour mieux comprendre :

    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
    #include <stdio.h>
    #include <stdlib.h>
     
    void allocat (int **pbmPic, int height);
     
    int main ()
    {
    	char t[12];
    	int **pbmPic;
     
    	allocat(pbmPic, 8);
     
    	pbmPic[1][34] = 1;
    	printf("\n test  =  %d   \n", pbmPic[1][34]);
     
    	return 0;
    }
     
    void allocat (int **pbmPic, int height)
    {	
    	int c = 0, l = 0;	
     
    	pbmPic = malloc((height + 1)*sizeof(int));
     
    	if (!pbmPic)
      	{
                printf("\nERREUR: echec de l'alloc. dyn. à la zone pixel (main)\n");
                exit(EXIT_FAILURE);
      	}
     
     	for (l = 0; l < (height + 1); l++)
     	{
       	    pbmPic[l] = malloc(240*sizeof(int*));
     
       	    if (!pbmPic[l])
       	    {
       		printf("\nERREUR: echec de l'alloc. dyn. à la zone pixel (sec.)\n");
     
       		for (c = 0; c < l; c++)
       		{
      	            free(pbmPic[c]);
      	        }
      	        free(pbmPic);
     
                    exit(EXIT_FAILURE);
      	    }
      	}
    }
    Ce n'est qu'une partie de mon projet mais c'est là qu'est le problème, j'en suis pratiquement certain. Bref ... si vous compilez ce code, il fonctionnera ... mais si vous changer la valeur 12 du "char t[12];" (dans le int main) par quelque chose de plus grand que 12 (plus petit ça fonctionne toujours) et bien j'obtiens une belle erreur de segmentation ...

    Je n'y comprend plus rien ... pourtant j'ai déjà utilisé cet algorithme pour créer des tableaux à 2 dimension mais sur des éléments de structure et pas directement sur un tableau présent dans une fonction et tout fonctionnait à merveille.

    Alors voilà, si vous pouviez m'éclairer sur ce point .. Je précise que je voudrais avoir les fonctions séparée, je sais déjà que cela fonctionne si on met tout dans le main.

    Ah et aussi, petite question, comment peut-on vérifier que la libération de la mémoire allouée (avec la fonction free() ) a bien fonctionné ?

  2. #2
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Salut,

    Le passage de paramètres en C se fait par copie. Un exemple simple,

    Pas bon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void ajoute1(int a)
    {
      a++;
    }
     
    int main()
    {
      int a=2;
      ajoute1(a);
      // ici a vaut toujours 2 car une copie de a a été passée 1 à ajoute1
    }
    Meilleur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void ajoute1(int *a)
    {
      (*a)++;
    }
     
    int main()
    {
      int a=2;
      ajoute1(&a);
      // ici a vaut 3. C'est comme avec scanf ...
      // une copie du pointeur est passée, mais comme la copie et
      // l'original pointent au même endroit ...
    }
    Tu devras donc avoir une déclaration du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void allocat (int *** ptr_pbmPic, int height);
    Dans ta version il y a une erreur, tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pbmPic = malloc((height + 1)*sizeof(int));
    or pbmPic est de type int**, le malloc devrait contenir un sizeof(int**) et non un sizeof(int).

    Une version (non testée, écrite à la volée) :
    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
    void allocat (int ***ptr_pbmPic, int height)
    {
      int c = 0, l = 0;
     
      /* correction du sizeof avec le type */
      *ptr_pbmPic = malloc((height + 1)*sizeof(int**));
     
      if (!(*ptr_pbmPic))
        {
          printf("\nERREUR: echec de l'alloc. dyn. à la zone pixel (main)\n");
          exit(EXIT_FAILURE);
        }
     
      for (l = 0; l < (height + 1); l++)
        {
          (*ptr_pbmPic)[l] = malloc(240*sizeof(int*));
     
          if (!((*ptr_pbmPic)[l]))
    	{
    	  printf("\nERREUR: echec de l'alloc. dyn. à la zone pixel (sec.)\n");
     
    	  for (c = 0; c < l; c++)
    	    {
    	      free(((*ptr_pbmPic)[c]));
    	    }
    	  free(*ptr_pbmPic);
     
    	  exit(EXIT_FAILURE);
    	}
        }
    }
    J'ai volontairement surchargé les écritures ...

    Dans le main tu pourras faire un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int** pbmPic;
    allocat(&pbmPic, 8);
    Il n'y a pas de moyen pour savoir si un free a échoué ou non. Tu peux vérifier si ton programme a des fuites de mémoire avec des outils comme valgrind.

  3. #3
    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
    Dans ta version il y a une erreur, tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pbmPic = malloc((height + 1)*sizeof(int));
    or pbmPic est de type int**, le malloc devrait contenir un sizeof(int**) et non un sizeof(int).
    Il devrait contenir un sizeof(int*) ou sizeof *pbmPic
    Mêmes erreurs dans le code proposé ensuite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *ptr_pbmPic = malloc((height + 1)*sizeof(int*));
    (*ptr_pbmPic)[l] = malloc(240*sizeof(int));
    Il serait d'ailleurs plus naturel de passer par la valeur de retour de la fonction. Du genre :

    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
    int ** allocat (int height)
    {
      int c ;
      int l ;
      int ** ptr_pbmPic = malloc((height + 1)*sizeof(int*)); 
      if (ptr_pbmPic==NULL) printf("\nERREUR: echec de l'alloc. dyn. à la zone pixel (main)\n");
      for (l = 0; ptr_pbmPic != NULL && l < (height + 1); l++)
      {
         ptr_pbmPic[l] = malloc(240*sizeof(int)); 
         if (ptr_pbmPic[l]==NULL)
         {
            printf("\nERREUR: echec de l'alloc. dyn. à la zone pixel (sec.)\n"); 
            for (c = 0; c < l; c++)free(ptr_pbmPic[c]);
            free(ptr_pbmPic);
            ptr_pbmPic = NULL;
         }
      }
      return ptr_pbmPic;
    }
    ....
    int* pbmPic;
    pbmPic = allocat(8);
    if(pbmPic==NULL) exit(EXIT_FAILURE);
    ....

  4. #4
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par diogene Voir le message
    Il devrait contenir un sizeof(int*) ou sizeof *pbmPic
    Mêmes erreurs dans le code proposé ensuite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *ptr_pbmPic = malloc((height + 1)*sizeof(int*));
    (*ptr_pbmPic)[l] = malloc(240*sizeof(int));
    ma faute, ne jamais répondre en état d'insomnie ...

    Il serait d'ailleurs plus naturel de passer par la valeur de retour de la fonction.
    C'est moins lourd en effet, mais ça dépend du style imposé.

  5. #5
    Membre averti
    Femme Profil pro
    Inscrit en
    Avril 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2012
    Messages : 12
    Par défaut
    Super ça fonctionne, merci beaucoup . Aussi, je ne savais pas que ça changeait quelque chose de marquer *pbmPic[l] ou (*pbmPic)[l].

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    Un message que j'ai précieusement conservé : http://www.developpez.net/forums/d11...g/#post6467166

Discussions similaires

  1. Erreur de segmentation allocation dynamique
    Par baguiwoopy dans le forum C
    Réponses: 8
    Dernier message: 28/04/2012, 21h48
  2. Gestion des erreurs, allocation dynamique
    Par mach1 dans le forum C
    Réponses: 11
    Dernier message: 02/05/2010, 19h19
  3. C++, erreur d'allocation dynamique de mémoire
    Par YuGiOhJCJ dans le forum C++
    Réponses: 8
    Dernier message: 20/02/2009, 11h51
  4. Erreur d'allocation dynamique de tableaux
    Par lclclc dans le forum Fortran
    Réponses: 1
    Dernier message: 02/04/2008, 15h10
  5. Réponses: 4
    Dernier message: 03/12/2002, 16h47

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