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

Windows Discussion :

Free, malloc et DLL


Sujet :

Windows

  1. #1
    Membre actif Avatar de Pikwik
    Profil pro
    Développeur Web
    Inscrit en
    Mai 2006
    Messages
    237
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Mai 2006
    Messages : 237
    Points : 252
    Points
    252
    Par défaut Free, malloc et DLL
    Pour avoir confirmation.

    J'ai une DLL à chargement Dynamique, dans cette DLL j'utilise malloc pour allouer de la mémoire pour une chaine, et ma fonction me retourne un pointeur.

    Arrétez moi si je me trompe, mais je ne peux pas faire de free(mon_pointeur) dans mon programme principal (car il ne connait pas la taille allouée ?), mais je peux faire une fonction, freeBuffer dans ma DLL qui s'occupe de le faire ?

    Enfin voila, si vous pouvez m'éclairer.

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    En théorie, tu n'es pas censé pouvoir le faire et tu dois faire une fonction freeBuffer() dans la DLL.
    En pratique, je sais que ça foirera en mode debug, pour le mode release je ne sais pas.

    Sinon, tu peux aussi utiliser les fonctions d'allocation Win32, qui n'ont pas ce problème : LocalAlloc()/GlobalAlloc() (plus ou moins deprecated), HeapAlloc(), VirtualAlloc()...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 671
    Points
    10 671
    Billets dans le blog
    3
    Par défaut
    Tu peux mélanger les free/malloc entre ton exe et ta dll si ces 2 utilisent le même couple free/malloc, c.a.d la même CRT (elle aussi sour forme de dll utilisée par les 2 autres). Ca dépend des options de compilation, et c'est jouer avec le feu

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 70
    Points : 57
    Points
    57
    Par défaut
    Par rapport à vos remarques, j'ai plusieurs questions:
    - j'ai 2 dll, chargées par la même application (que j'appellerais dll1 et dll2). Dans dll1 j'ai une fonction qui fait un malloc sur une variable passé en paramètre de la fonction, dans dll2 j'ai une fonction qui fait un free sur cette même variable.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    DLL1
    void fct1 (StructPerso *part)
    {...}
    part->var = (char*)malloc(256*sizeof(char));
    strcpy(part->var, "OK");
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    DLL2
    void fct2
    {...}
    StructPerso part;
    fct1(&part);
    if(part.var != NULL) free(part.var);
    part.var = NULL;
    Ce code crash.
    Si je met l'allocation dans la même dll (DLL2), aucun souci.
    Je n'ai pas d'écrasement mémoire, j'ai vérifié.
    D'après vos commentaires, ce problème est peut-être normal?
    - si c'est le cas, est-ce que vous avez une référence (documentation web sur malloc/free ou autre) qui m'aiderai à argumenter (car il faut que j'explique pourquoi cette méthode d'allocation ne peut pas fonctionner)? j'ai beau chercher sur le net, je ne trouve rien sur malloc/free entre 2 dll.
    - dernière question, il peut y avoir une différence de comportement entre Windows XP et Vista?
    Merci d'avance.

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    En effet, ce genre de crash est normal.
    La règle de base avec malloc/free, c'est "ce qui est alloué par un module doit être libéré par le même module".

    Il faut donc que DLL1 expose une fonction spécifique pour libérer la mémoire qu'elle a allouée.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void fct1 (StructPerso *part)
    {
    	...
    	part->var = malloc(256*sizeof(*part->var));
    	strcpy(part->var, "OK");
    	...
    }
     
    void freefct1(char * p)
    {
    	free(p);
    }
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void fct2
    {
    	...
    	StructPerso part;
    	fct1(&part);
    	freefct1(part.var);
    	part.var = NULL;
    	...
    }

    Par contre, de là à trouver une référence officielle...
    Tu peux chercher par ici:
    C Run-Time Libraries
    Allocating and freeing memory across module boundaries

    PS: Le coup de l'utilisation de fonctions Windows comme LocalAlloc() etc. suit le même principe:
    • LocalAlloc() et LocalFree() sont dans Kernel32.DLL, Ainsi que GlobalAlloc()/GlobalFree() et HeapAlloc()/HeapFree().
    • CoTaskMemAlloc() et CoTaskMemFree() sont dans Ole32.DLL
    • SysAllocString() et SysFreeString() sont dans OleAut32.DLL, ainsi que SafeArrayCreate() et SafeArrayDestroy().
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par polonain2 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    DLL1
    void fct1 (StructPerso *part)
    {...}
    part->var = (char*)malloc(256*sizeof(char));
    strcpy(part->var, "OK");
    le cast du retour de malloc() est inutile sinon dangereux.
    sizeof(char) renverra toujours 1.
    je conseille :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    part->var = malloc (256 * sizeof *part->var);
    Citation Envoyé par polonain2 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    DLL2
    void fct2
    {...}
    if(part.var != NULL) free(part.var);
    part.var = NULL;
    soit tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (part.var != NULL) 
    {
       free (part.var);
       part.var = NULL;
    }
    soit tu peux faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    free (part.var);
    part.var = NULL;
    et généralement on faît même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    free (part.var), part.var = NULL;
    en revanche pour ton soucis de malloc/free, je trouve bizarre ce comportement sous windows, dans la mesure ou les DLL partagent le même espace d'adressage, il ne devrait pas y avoir de problème. J'attends les explications d'un gourou...
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  7. #7
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    La règle de base avec malloc/free, c'est "ce qui est alloué par un module doit être libéré par le même module".
    Aurais tu une référence dans la norme appuyant tes propos ?
    "The quieter you become, the more you are able to hear"
    "Plus vous êtes silencieux, plus vous êtes capable d'entendre"

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Aurais tu une référence dans la norme appuyant tes propos ?
    Non, et je ne sais même pas si la norme connait la notion de "module" telle que je l'utilise (j'utilise la notion Windows de "module", qui signifie "EXE ou DLL").
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 70
    Points : 57
    Points
    57
    Par défaut
    Ok merci pour vos réponses ultra rapide
    Avec les liens donnés ci-dessus j'ai trouvé ça:
    http://msdn.microsoft.com/en-us/libr...60(VS.80).aspx
    A related problem can occur when you allocate memory (either explicitly with new or malloc, or implicitly with strdup, strstreambuf::str, and so on) and then pass a pointer across a DLL boundary to be freed. This can cause a memory access violation or heap corruption if the DLL and its users use different copies of the CRT libraries.
    Alors j'ai un peu de mal à concevoir le terme "CRT". Si j'ai bien compris, si j'utilise la même version du compilateur (ce qui est le cas, j'utilise VS2003 pour les 2 dll), je ne devrais pas avoir le problème? Est-ce que le terme CRT peut "s'appliquer" aux options de compilations?

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 70
    Points : 57
    Points
    57
    Par défaut
    OK je viens de comprendre. Je vais vérifier mes options de compilation et de link.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 70
    Points : 57
    Points
    57
    Par défaut
    ok. Alors je ne sais pas trop ce que ça signifie pour mon problème mais je n'utilise pas les options de compilations présenté sur http://msdn.microsoft.com/en-us/libr...yh(VS.80).aspx

    Donc si je me réfère à la remarque (sur le même lien):
    If you link your program from the command line without a compiler option that specifies a C run-time library, the linker will use LIBCMT.LIB. This is different from previous versions of Visual C++ which used LIBC.LIB, the single-threaded library, instead.
    J'utilise donc l'option LIBC.LIB (la doc concerne VS2005 et moi j'utilise VS2003)
    Donc mes 2 libraries utilisent la même lib CRT.
    Est-ce que mon crash peut être lié au fait d'utiliser des dll single-thread?

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Avec LIBC.LIB, tes DLLs n'utilisent pas la même CRT : LIBC.LIB étant une CRT statique, chaque DLL (ainsi que l'Exe) possède sa propre instance de la CRT, donc son propre tas, ses propres descripteurs de fichiers, etc.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 70
    Points : 57
    Points
    57
    Par défaut
    Ok donc j'avais rien compris au CRT
    Je vais tester avec une lib dynamique.

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 70
    Points : 57
    Points
    57
    Par défaut
    C'est bon j'ai plus de crash si j'utilises l'option /MD lors de la compilation. Merci à tous. (je ferme pas le post en résolu, c'est pas le mien)

  15. #15
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 671
    Points
    10 671
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    en revanche pour ton soucis de malloc/free, je trouve bizarre ce comportement sous windows, dans la mesure ou les DLL partagent le même espace d'adressage, il ne devrait pas y avoir de problème. J'attends les explications d'un gourou...
    C'est comme si sous Linux chaque .so utilisait sa propre couple de fonctions malloc/free dans des implementation "maison"...

    Ca ne pose pas de probleme avec les fonctions citees par Medinoc (LocalAlloc/LocalFree, etc...) parce que ces fonctions sont dans des dlls systemes utilisees par tous les processus. Mais malloc/free, c'est fourni par le compilateur... dans la fameuse "CRT". Le truc c'est qu'il est assez facile de se retrouver avec plusieurs CRT en memoire. Ca peut etre des CRT differentes ou plusieurs fois la meme CRT (le cas ici), ce qui ne change rien en fait.

Discussions similaires

  1. free (), crash ntdll.dll
    Par _iri_ dans le forum Bibliothèque standard
    Réponses: 6
    Dernier message: 18/09/2010, 00h09
  2. Réponses: 3
    Dernier message: 27/02/2006, 08h52
  3. malloc et free
    Par petdelascar dans le forum C
    Réponses: 6
    Dernier message: 15/01/2006, 21h08
  4. free/malloc
    Par Duguesclin dans le forum C
    Réponses: 3
    Dernier message: 09/01/2005, 19h04
  5. malloc et free
    Par barthelv dans le forum C
    Réponses: 3
    Dernier message: 22/07/2003, 18h34

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