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 :

probleme a la liberation de la memoire


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2011
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 96
    Par défaut probleme a la liberation de la memoire
    Bonjour

    Le code suivant compile (gcc -Wall -Werror -o point.exe point.c)


    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
     
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct {
     
    						int x;
    						int y;
    					}Point;
     
    void test(int nb) {
     
    	Point* p = malloc(nb * sizeof(Point));
     
    	int i;
    	for(i = 0 ; i < (2 * nb) ; i++) {
     
    		p[i].x = i;
    		p[i].y = i + 1;
     
    	}
     
     
    	for(i = 1 ; i <= nb ; i++) {
     
    		printf("du point numero %d, l'abscisse vaut %d et l'ordonnee vaut %d \n", i, p[i].x, p[i].y);
     
    	}
     
    	printf("fin affichage debut liberation memoire\n");
     
    	free(p);
     
    	printf("sortie de la fonction test\n");
     
    }
     
     
     
    int main (int argc, char* argv []) {
     
    	int param = atoi(argv[1]);
     
    	test(param);
     
    	printf("retour dans le main \n");
     
    	return 0;
     
    }
    l'execution par: point.exe 6 donne
    du point numero 1, l'abscisse vaut 1 et l'ordonnee vaut 2
    du point numero 2, l'abscisse vaut 2 et l'ordonnee vaut 3
    du point numero 3, l'abscisse vaut 3 et l'ordonnee vaut 4
    du point numero 4, l'abscisse vaut 4 et l'ordonnee vaut 5
    du point numero 5, l'abscisse vaut 5 et l'ordonnee vaut 6
    du point numero 6, l'abscisse vaut 6 et l'ordonnee vaut 7
    fin affichage debut liberation memoire

    puis cesse de fonctionner si qlq'un peut m'expliquer mon erreur ou la cause

    d'avance merci

  2. #2
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 254
    Par défaut
    Ok voici trois lignes incohérentes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Point* p = malloc(nb * sizeof(Point));
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for(i = 0 ; i < (2 * nb) ; i++)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for(i = 1 ; i <= nb ; i++)
    Dans la première tu alloue un tableau de point de taille nb.

    Dans la deuxième tu parcours ce tableau en le remplissant, sauf que tu met 2*nb. Donc en gros tu dépasse la fin de ton tableau (c'est mal).

    Dans la troisième, tu parcours ton tableau nb-1 fois.

    Soit la deuxième ligne est fausse et tu devrai mettre nb au lieu de 2*nb, soit c'est la première et la troisième qui sont fausse et dans ce cas, tu doit mettre 2*nb a la place de nb

  3. #3
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Bonjour.
    Si ton programme plante, c'est que tu vas taper là où tu ne devrais pas...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #line 13 "point.c"
    	Point* p = malloc(nb * sizeof(Point));
    Tu alloues de la mémoire pour nb éléments de type Point.
    Jusque là, tout va bien.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #line 16 "point.c"
    	for(i = 0 ; i < (2 * nb) ; i++) {
     
    		p[i].x = i;
    		p[i].y = i + 1;
     
    	}
    Là, tu fais varier ton indice de 0 à 2 * nb, ce qui fait donc 2 * nb éléments.
    Or on a dit juste au-dessus que tu avais réservé de la mémoire pour seulement nb éléments.

    La suite est simple à comprendre.
    Pour les nb premières itérations de ta boucle, tu écris bien dans la zone que tu as réservé.
    Mais pour les suivantes, tu écris dans une zone mémoire qui ne t'appartient pas.
    Au mieux, elle n'est jamais utilisée lors de l'exécution du programme, et alors ce n'est pas grave ; au pire, on atteint une zone système, et le fait d'écrire dessus peut avoir des conséquences catastrophiques...

    Rappelle-toi bien que les éléments d'un tableau de taille n sont indicés de 0 à n-1.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #line 24 "point.c"
    	for(i = 1 ; i <= nb ; i++) {
     
    		printf("du point numero %d, l'abscisse vaut %d et l'ordonnee vaut %d \n", i, p[i].x, p[i].y);
     
    	}
    Comme on dit :
    Les mêmes causes entraînent les mêmes effets.
    Encore une fois, les bornes pour l'indice du tableau sont mauvaises.
    Comme dit précédemment : les éléments d'un tableau de taille n sont indicés de 0 à n-1.


    Bon courage !

    Edit: grilled...

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2011
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 96
    Par défaut
    Bonjour

    Merci pour vos réponses.
    Effectivement il y avait une erreur de borne lors de l'écriture (cas d'arrêt a nb et non 2 * nb).
    Ainsi qu'a la lecture l'accès aux variables devait êtres décalé de 1.

    Ce qui marche une fois corrige et donne le code suivant. (modifications en rouge italique taille 5)

    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
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct {
    
    						int x;
    						int y;
    					}Point;
    
    void test(int nb) {
    
    	Point* p = malloc(nb * sizeof(Point));
    	
    	int i;
    	for(i = 0 ; i < nb ; i++) {
    	
    		p[i].x = i;
    		p[i].y = i + 1;
    	
    	}
    	
    
    	for(i = 1 ; i <= nb ; i++) {
    	
    		printf("du point numero %d, l'abscisse vaut %d et l'ordonnee vaut %d \n", i, p[i - 1].x, p[i - 1].y);
    	
    	}
    	
    	printf("fin affichage debut liberation memoire\n");
    	
    	free(p);
    	
    	printf("sortie de la fonction test\n");
    	
    }
    
    					
    					
    int main (int argc, char* argv []) {
    
    	int param = atoi(argv[1]);
    
    	test(param);
    	
    	printf("retour dans le main \n");
    	
    	return 0;
    
    }
    Merci encore pour votre attention

  5. #5
    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
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int param = atoi(argv[1]);
    1) Il faut vérifier argc avant d'utiliser les pointeurs dans le tableau argv. Car si tu débordes, il y a risque de crash.

    2) atoi a un gros problème : la fonction ne donne aucune information lors d'une erreur de conversion ; il est préférable de ne pas l'utiliser. Utilise strtol à la place.

  6. #6
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	for(i = 1 ; i <= nb ; i++) {
    	
    		printf("du point numero %d, l'abscisse vaut %d et l'ordonnee vaut %d \n", i, p[i - 1].x, p[i - 1].y);
    	
    	}
    Personnellement, j'aurai plutôt fait ça, mais ça fonctionne aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	for(i = 0 ; i < nb ; i++) {
    	
    		printf("du point numero %d, l'abscisse vaut %d et l'ordonnee vaut %d \n", i + 1, p[i].x, p[i].y);
    	
    	}

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

Discussions similaires

  1. liberer l'espace memoire
    Par ralf91 dans le forum C
    Réponses: 9
    Dernier message: 21/04/2007, 09h44
  2. Liberer de la memoire avec une image
    Par Battosaiii dans le forum Langage
    Réponses: 1
    Dernier message: 19/07/2006, 17h02
  3. tester si mon programme a liberer toute la memoire
    Par Mokhtar BEN MESSAOUD dans le forum C
    Réponses: 2
    Dernier message: 14/11/2005, 16h55
  4. [JVM]Libérer de la mémoire
    Par Vrylx dans le forum Général Java
    Réponses: 8
    Dernier message: 13/10/2005, 16h58
  5. comment demander a un serveur sql de liberer de la memoire
    Par timsah dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 07/09/2005, 11h24

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