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 :

Peut-on libérer la mémoire avec free quand on a pas défini un pointeur au départ?


Sujet :

C

  1. #1
    Membre du Club
    Homme Profil pro
    Statistique
    Inscrit en
    Octobre 2014
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Statistique

    Informations forums :
    Inscription : Octobre 2014
    Messages : 33
    Points : 48
    Points
    48
    Par défaut Peut-on libérer la mémoire avec free quand on a pas défini un pointeur au départ?
    Bonjour

    Je cherche à savoir s'il est possible de libérer la mémoire occupée par une variable lorsqu'on a créé cette variable de manière «directe» (sans passer par un pointeur).
    Un code pour illustrer:

    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
    int main(int argc, char *argv[])
    {
            // Premier bloc d'instructions.
    	int *a; 
    	a = malloc (sizeof(int)); // En une seule ligne int *a = malloc (sizeof(int)); ça va aussi.
    	printf("L'adresse de a, c'est à dire l'adresse du pointeur sur *a  est %p. \n", &a);
    	printf("L'adresse de *a, c'est a dire a est %p. \n", a);
    	*a = 25;
    	printf("*a = %d. \n", *a);	
    	free(a); // Ca marche (pas de message d'erreur).	
     
     
    	// Deuxième bloc d'instructions.
    	int *b;
    	printf("L'adresse de b, c'est à dire l'adresse du pointeur sur *b  est %p. \n", &b);
    	printf("L'adresse de *b, c'est a dire b est %p. \n", b);
    	*b = 75;
    	printf("*b = %d. \n", *b);	
    	free(b); // Ca ne marche pas
    	// A l'exectuion -> Erreur de segmentation (core dumped)
     
     
    	/*// Troisième bloc d'instructions.
    	int c = 5;
    	free(&c); // Ca ne marche pas. 
    	//A la compilation ->  "warning: attempt to free a non-heap object ‘b’ [-Wfree-nonheap-object]"*/
    }
    Dans le troisième bloc d'instruction je crée la variable c de manière «directe» mais quand j'applique la fonction «free» à &c ça ne marche pas. Pourtant &c est un pointeur non? Savez vous comment je devrais faire ici?

    J'en profite pour vous demander ce que vous pensez du deuxième bloc d'instruction. J'ai oublié d'attribuer de la mémoire à b, et pourtant je peut attribuer une valeur à *b. Vous en pensez quoi? C'est normal?

    Merci à qui pourra répondre. :-)

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par Obofix le gaulois Voir le message
    Pourtant &c est un pointeur non? Savez vous comment je devrais faire ici?
    Oui mais la variable c est créée sur la pile ... non sur le tas

  3. #3
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    free ne libère pas un pointeur, mais le bloc mémoire issu du tas désigné par un pointeur.

    En fait, les pointeurs en eux même n'ont rien à voir avec free et malloc.

    Les pointeurs sont des variables contenant une adresse l'adresse d'un bloc mémoire à traiter comme d'un type donnée.
    Ainsi, int *p; déclare en gros "soit de type entier ce que désigne p". p peut contenir n'importe quelle adresse d'un entier.

    Une adresse s'obtient comme la valeur d'un autre pointeur, ou par l'application de l'opérateur & (unaire) sur quelque chose qui existe en mémoire (pas la valeur 2, par exemple) et du bon type.


    Les fonctions free et malloc utilisent un pointeur (en argument ou en valeur de retour, respectivement).

    malloc réclame au système un bloc mémoire venant du "tas" ("heap"), et free libère un tel bloc (le système est averti qu'il peut s'en servir pour autre chose).

    Ces transitions entre l'état "alloué" et l'état "libre" doivent être faite proprement: un même bloc ne doit jamais évoluer deux fois dans le même sens.

    Tout bloc alloué doit être libéré. Dans le cas contraire, on parle de fuite mémoire: certains blocs mémoires cessent d'être disponible, amenant à des crash de type "out of memory"
    Seul un bloc alloué peut être libéré. Dans le cas contraire, tu rencontres un message du type "double free or corruption".

    L'énorme problème des allocations dynamiques, c'est donc de proprement gérer les pointeurs.
    Pour ne pas perdre l'adresse des blocs à libérer, on devrait toujours libérer de manière symétrique: soit dans le même bloc, soit par une paire de fonctions symétriques (à la façon de fopen et fclose qui manipulent des pointeurs de fichiers).
    Pour ne pas les conserver trop longtemps, il convient de toujours remettre à NULL un pointeur qui est libéré (à moins qu'on sorte immédiatement de son bloc de définition)
    Le premier
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  4. #4
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    J'ai oublié de rappeler qu'en temps normal, une variable est uniquement définie dans le bloc contenant sa définition.
    Sa mémoire (issue de la pile) est automatiquement libérée à la sortie du bloc.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  5. #5
    Membre du Club
    Homme Profil pro
    Statistique
    Inscrit en
    Octobre 2014
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Statistique

    Informations forums :
    Inscription : Octobre 2014
    Messages : 33
    Points : 48
    Points
    48
    Par défaut
    Merci beaucoup pour vos réponses. Je n'avais pas bien conscience qu'on faisait appel à deux mémoires différentes ici. J'en avais très brièvement entendu parlé en étudiant C++ il y a plusieurs années mais ce n'était pas clair pour moi à l'époque.

    Les choses sont plus claires, merci bien.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 25/10/2011, 09h49
  2. [Flex4] Libérer la mémoire (DataGrid avec Renderer)
    Par npirard dans le forum Flex
    Réponses: 6
    Dernier message: 23/08/2010, 14h37
  3. Problème de libération de mémoire avec free()
    Par Nival dans le forum Débuter
    Réponses: 8
    Dernier message: 18/03/2009, 23h06
  4. Libérer de la mémoire avec la destruction de contrôles!
    Par NejNej dans le forum Windows Forms
    Réponses: 4
    Dernier message: 22/01/2009, 13h36
  5. [free] dois-je libérer la mémoire ?
    Par bulki dans le forum C
    Réponses: 9
    Dernier message: 15/05/2007, 15h59

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