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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté 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
    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
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 413
    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 confirmé

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

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    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 confirmé
    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
    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
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 413
    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 Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    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 ?

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

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    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...

  8. #8
    Expert confirmé

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

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 756
    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