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 :

"void*","char*" et fuite mémoire.


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Operateur electronique
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Operateur electronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 5
    Points
    5
    Par défaut "void*","char*" et fuite mémoire.
    Bonjour tout le monde.

    j'utilise Visual c++ 2008.
    Je m'attaque sérieusement au pointeur et j'aurais aimé savoir si ce petit programme (qui fonctionne) ne crée pas de problème (fuite mémoire et autre):

    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>
    #include <string.h>[/B]
     
    int main(int argc, char *argv[])
    {	
    	void* vp;
    	char* cp;
    	vp=(void*)malloc(sizeof(char*));
    	vp="a333";
    	printf("%s\n",vp);
    	vp="a22";
    	cp=(char*)vp;
    	vp=NULL;
    	free(vp);
    	printf("%s\n",cp);
    	cp="a1";
    	printf("%s\n",cp);
    	system("PAUSE");	
    	return 0;
    }

  2. #2
    CGi
    CGi est déconnecté
    Expert éminent
    Avatar de CGi
    Inscrit en
    Mars 2002
    Messages
    1 030
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 1 030
    Points : 8 202
    Points
    8 202
    Par défaut
    Oui, il y a une fuite mémoire !

    Tu alloues de la mémoire et tu mets l'adresse de cette zone mémoire dans le pointeur vp. Là c'est bon !
    Ensuite tu fait pointer ce pointeur sur une chaîne de caractère. Donc à ce moment là, tu perds l'adresse de la zone mémoire que tu y avais mis auparavant !
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Points : 176
    Points
    176
    Par défaut
    A première vue je dirais que si , même si je suis loin d'être un grand spécialiste du domaine

    Pourquoi ne pas mettre char* ? Même si c'est correct je pense qu'il vaut mieux éviter des variables de type void* sauf dans des cas particuliers. Après je conçois tout à fait que tu souhaites t'entraîner

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    vp=(void*)malloc(sizeof(char*));
    vp="a333";
    Tu déclares allouer la taille d'un pointeur de char, c'est à dire sur beaucoup de machines 4 octets. Cependant cela ne sert à rien puisque tu déclares ensuiteDonc il y a fuite de mémoire puisque tu ne libères pas ce que tu as alloué avant d'écrire vp="a333";

    Il faut donc ici écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vp=(void*)malloc(X*sizeof(char));
    Avec X le nombre de caractères que tu souhaites mettre dans ta chaîne (ici 4 donc) et faire ensuite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    *vp = 'a';
    *(vp+1) = '3';
    *(vp+2) = '3';
    *(vp+3) = '3';
    Ou sinon tu déclares directement :
    Ensuite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    vp=NULL;
    free(vp);
    Mettre à nul le pointeur ne sert à rien si tu libères ce pointeur après donc ici le est totalement inutile. D'ailleurs si tu l'avais mis avant la mise à 0 du pointeur tu aurais eu une fuite de mémoire, car, lorsque tu déclares cela signifie que le pointeur cp va prendre la valeur du pointeur vp, donc si tu libères vp à cet instant, cp ne va pointer sur plus rien.
    Donc "Heureusement" encore une fois que tu ais mis le pointeur vp à NULL avant de le libérer, sinon tu aurais eu une fuite

    Enfin, tu as une dernière fuite de mémoire puisque tu n'appelle pas free() pour libérer le pointeur cp, anciennement vp, mais comme tu as mis vp à NULL tu dois libérer cp, sinon tu aurais eu le choix entre libérer l'un ou libérer l'autre mais pas les 2 ! Si tu as besoin d'autres explications n'hésite pas !

    Edit : CGi dit plus ou moins la même chose en omettant toutefois la dernière fuite de mémoire (ou alors c'est moi qui me trompe )

    Edit bis : je dirais que ce code est correct :
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main(int argc, char *argv[])
    {
    void* vp;
    char* cp;
    vp=(void*)malloc(sizeof(char)*//ce que tu veux//); //ligne ici totalement inutile
    free(vp); //inutile si ligne précédente absente
    vp="a333";
    printf("%s\n",vp);
    vp="a22";
    cp=(char*)vp;
    printf("%s\n",cp);
    free(cp); // ou free(vp) puis vp=NULL;
    cp="a1";
    printf("%s\n",cp);
    //plus besoin de libérer cp ni de le mettre à NULL
    system("PAUSE");	
    return 0;
    }

  4. #4
    CGi
    CGi est déconnecté
    Expert éminent
    Avatar de CGi
    Inscrit en
    Mars 2002
    Messages
    1 030
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 1 030
    Points : 8 202
    Points
    8 202
    Par défaut
    Voir commentaires dans code :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    //#include <string.h> // Pas utile ici
    int main(void)
    {
        void* vp;
        char* cp;
        vp = (void*)malloc(sizeof(char*)); // Transtypage pas necessaire et taille pas bonne.
        vp = "a333"; // ICI tu perds l'adresse de ton bloc mémoire
        printf("%s\n",(char*)vp); //Là tu peux mettre un transtypage
                                    // pour éviter le warning
        vp="a22";
        cp=(char*)vp;
        vp=NULL;  // On met le pointeur à null
        free(vp); // après avoir libéré la mémoire.
        printf("%s\n",cp);
        cp="a1";
        printf("%s\n",cp);
        system("PAUSE"); // "Pause" spécifique à Windows
        return 0;
    }
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Operateur electronique
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Operateur electronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 5
    Points
    5
    Par défaut
    Merci les gars!

    J'utilise void* car j'ai dans l'idée de créer un struct qui en contienne pour y stocker des int,char*,et float.je ferai des cast pour récuperer les valeurs.

    Donc en gros,a chaque fois que je cherche a envoyer une chaine dans un pointeur qui a déja initialisé,il va pointer sur une nouvelle zone mémoire sans libérer la précédente?

    Et ça,c'est correcte?

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main(int argc, char *argv[])
    {	
    	void* vp;
    	vp="a333";
    	printf("%s\n",(char*)vp);
    	free(vp);
    	vp="a22";
    	printf("%s\n",(char*)vp);
    	free(vp);
    	system("PAUSE");	
    	return 0;
    }

  6. #6
    Membre éprouvé
    Avatar de mitkl
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2010
    Messages
    364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2010
    Messages : 364
    Points : 1 081
    Points
    1 081
    Par défaut
    non, il n'y a rien à free
    Si vous ne savez toujours pas ce qu’est la récursivité, relisez cette phrase.

    Mon blog sur la programmation et l'informatique !

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Operateur electronique
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Operateur electronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 5
    Points
    5
    Par défaut
    Ok.

    Donc je crois que je vais utiliser la solution de Lintel-oo,je vais utiliser "vp=(void*)malloc(X*sizeof(char));".

    Merci a tous!

  8. #8
    CGi
    CGi est déconnecté
    Expert éminent
    Avatar de CGi
    Inscrit en
    Mars 2002
    Messages
    1 030
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 1 030
    Points : 8 202
    Points
    8 202
    Par défaut
    Citation Envoyé par Lintel-oo
    CGi dit plus ou moins la même chose en omettant toutefois la dernière fuite de mémoire
    Il n'y a qu'une seule fuite mémoire. Par contre dans ton code (Edit Bis) il y a un free de trop !

    @Zeeraptor, si c'est copier une chaîne de caractères dans la zone mémoire que tu avais allouée que tu désirais faire, c'est strcpy ou strncpy qu'il faut utiliser.

    Et pour l'allocation avec malloc, c'est un malloc un free.
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Operateur electronique
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Operateur electronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 5
    Points
    5
    Par défaut
    Et ça c'est possible?

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    void* str2void(char* str)
    {	
    	void* vp;
    	vp=(void*)malloc(sizeof(char)*(strlen(str)+1));
    	strcpy((char*)vp,str);
    	return vp;
    }
     
    int main(int argc, char *argv[])
    {	
    	void* vp=str2void("go1");
    	printf("%s",(char*)vp);
    	free(vp);
    	vp=NULL;
    	vp=str2void("go2");
    	printf("%s",(char*)vp);
    	free(vp);
    	vp=NULL;
    	system("PAUSE");	
    	return 0;
    }

  10. #10
    CGi
    CGi est déconnecté
    Expert éminent
    Avatar de CGi
    Inscrit en
    Mars 2002
    Messages
    1 030
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 1 030
    Points : 8 202
    Points
    8 202
    Par défaut
    Ça me semble bon !

    Le transtypage sur le retour de malloc n'est pas nécessaire.
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Operateur electronique
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Operateur electronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 5
    Points
    5
    Par défaut
    Je peux donc faire ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vp=malloc(sizeof(char)*(strlen(str)+1));

  12. #12
    CGi
    CGi est déconnecté
    Expert éminent
    Avatar de CGi
    Inscrit en
    Mars 2002
    Messages
    1 030
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 1 030
    Points : 8 202
    Points
    8 202
    Par défaut
    Tout à fait !
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Operateur electronique
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Operateur electronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 5
    Points
    5
    Par défaut
    Merci!

    j'ai bien fait de m'inscrire au forum.

    A plus peut être(pour les pointeurs de fonction).

  14. #14
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Points : 176
    Points
    176
    Par défaut
    @CGi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    il y a un free de trop !
    Autant pour moi désolé pour cette erreur même si je vois que le sujet est résolu

  15. #15
    Membre chevronné
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Points : 1 800
    Points
    1 800
    Par défaut
    Citation Envoyé par CGi Voir le message
    Tout à fait !
    Je souligne tout de meme que meme si le transtypage n'est pas neccessaire, il faut toutefois garder a l'esprit que si ton code passe par un copilateur C++ tu auras des problemes.
    dans ton cas c'est du C et rien que du C donc ca va. mais dans mon cas je suis obliger de transtyper car mes collegues font du C++ et utilise mes fonctions ecrite en C et ca cale quand je ne le fais pas.

    juste une info quoi
    Petit lien vers mon premier jeux SDL2/C
    http://store.steampowered.com/app/72..._Soul_Of_Mask/
    la suite? ca vient,ca vient!

  16. #16
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Pour savoir si ton code a des fuites mémoire, le mieux est d'utiliser un débogueur mémoire. Sous Linux / Unix, on utilise généralement Valgrind. Sous Windows, tu peux utiliser Dr Memory. J'ai fait un post sur cet outil : http://www.developpez.net/forums/d12...ows-and-linux/

    PS : pourquoi faire chaine = "toto"; après un malloc émet une fuite ? C'est parce que malloc est une allocation dynamique quand chaine = "toto"; est une allocation statique. Tu peux regarder ce thread et ce message à propos.

  17. #17
    Futur Membre du Club
    Homme Profil pro
    Operateur electronique
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Operateur electronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 5
    Points
    5
    Par défaut
    je vais donc transtypé.je compile en c++,parce que j'utile les surcharges et occasionellement les templates.

    Donc: allocation statique->donnée constante->donnée non modifiable.

    je commence a y voir plus clair sur le fonctionnement du compilateur.

    Dr memory peut-ètre intéréssant pour corriger les fautes.Je m'en servirais certainement pour de gros programmes.

    Encore merci les Gars!

  18. #18
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Si tu utilises des templates et des surcharges, alors tu codes en C++. Pourquoi ne pas utiliser les fonctions C++ new() et delete() dans ce cas ?

  19. #19
    CGi
    CGi est déconnecté
    Expert éminent
    Avatar de CGi
    Inscrit en
    Mars 2002
    Messages
    1 030
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 1 030
    Points : 8 202
    Points
    8 202
    Par défaut
    Citation Envoyé par lilington Voir le message
    Mais dans mon cas je suis obliger de transtyper car mes collegues font du C++ et utilise mes fonctions ecrite en C et ca cale quand je ne le fais pas.
    juste une info quoi
    Oui en fesant des copier collé du code, mais si tu mets tes fonctions C
    dans des fichiers séparées C ou des lib écrite en C, le C++ est tout à fait capable de s'interfacer avec.
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  20. #20
    Futur Membre du Club
    Homme Profil pro
    Operateur electronique
    Inscrit en
    Juillet 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Operateur electronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2012
    Messages : 13
    Points : 5
    Points
    5
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Si tu utilises des templates et des surcharges, alors tu codes en C++. Pourquoi ne pas utiliser les fonctions C++ new() et delete() dans ce cas ?
    Je préfere rester au maximum dans l'esprit C.J'utilise la surcharge parce ce que c'est bien pratique,et que c'est très simple a utiliser (je ne comprend pas pourquoi il ne l'intègre pas au C standard).Les templates peuvent être pratique aussi,mais la syntaxe est C++,dons j'évite de les utiliser.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. UPDATE en ajoutant un 0 sur un champ de type "char"
    Par doum2 dans le forum Requêtes
    Réponses: 1
    Dernier message: 08/03/2006, 14h22

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