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 :

Problème de désallocation mémoire dans un bibliothèque


Sujet :

C

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2006
    Messages : 147
    Points : 84
    Points
    84
    Par défaut Problème de désallocation mémoire dans un bibliothèque
    Bonjour,

    Je ne suis pas très calé en C, mais j'ai besoin de quelques fonctions plus faciles à écrire en C qu'en Pascal. J'ai donc une petite librairie statique C avec quelques fonctions que je lie avec mon appli Pascal. Tout va bien, sauf la désallocation de la mémoire. Je m'explique:

    Dans mon programme Pascal, j'appelle une fonction P qui appelle une fonction C1 écrite en C. Je récupère dans P un pointeur sur une structure pour laquelle C1 a alloué la mémoire nécessaire, je lis cette structure dans ma fonction P, et quand j'ai terminé, j'appelle une fonction C2 écrite en C qui libère la mémoire allouée dans C1. C'est là que ça bug. J'obtiens ce message au moment de la désallocation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    *** error for object 0x1057a8c: pointer being freed was not allocated
    *** set a breakpoint in malloc_error_break to debug
    Voici la fonction C1 écrite en C (Alloue la mémoire):
    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
     
    size_t GetBSDProcessListSimple(procsimple ** proclistsimple)
    {
    	int err, i, j;
    	kinfo_proc *       process;
    	procsimple *       result;
    	size_t             processCount;
     
    	err = GetBSDProcessList(&process, &processCount);
    	result = (procsimple*)malloc(processCount * sizeof(procsimple));
    	for (i=0; i< processCount; i++) {
    		result[i].p_pid = process[i].kp_proc.p_pid;
    		for (j=0; j<128; j++) {
    	            result[i].p_comm[j] = process[i].kp_proc.p_comm[j];
    		}
    	}		
    	*proclistsimple = result;
    	free(process);
    	return processCount;
    };
    Voici la fonction C2 écrite en C (libère la mémoire):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int ReleaseProcessListSimple(procsimple ** proclistsimple)
    {
    	procsimple *       result;
    	result = *proclistsimple;
    	free(result);
    	return 0;
    };

    Voici la fonction P écrite en Pascal qui appelle les deux fonctions précédentes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    // Remplit la StringList avec <ProcessName>,<ProcessId>
    function GetProcess (var ProcessList:Tstringlist) : size_t; // OK
    var
    i: integer;
    PProcList: p_procsimple;
    begin
        result := cfun.GetBSDProcessListSimple(@PProcList);
        for i:=0 to result - 1 do begin
            ProcessList.Add(PChar(PProcList^.p_comm) + ',' +    IntToStr(PProcList^.p_pid));
            PProcList := PProcList + (SizeOf(PProcList^) div result);
        end;
        cfun.ReleaseProcessListSimple(@PProcList);
     end;

    Pour rappel, la librairie C n'est pas une DLL, elle est liée statiquement à programme Pascal lors de la compilation (Environnement Mac OS X)

    Comme je maîtrise très mal C, je ne fais peut être pas le free sur le bon pointeur.

    Merci,
    André.

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2010
    Messages : 33
    Points : 39
    Points
    39
    Par défaut
    Moi je ne suis pas très doué en pascal... Mais bon, en C, je me débrouille...
    Du coup j'ai une remarque sur la fonction qui alloue la mémoire:
    Tu alloues un pointeur result, mais tu ne retourne jamais le pointeur de ce tableau nulle part, donc il me semble normal qu'il soit perdu? Ou alors c'est la mise en commun avec le Pascal que je ne comprend pas?

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2006
    Messages : 147
    Points : 84
    Points
    84
    Par défaut
    Alors quand j'appelle la fonction de puis le Pascal, je passe un pointeur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    result := cfun.GetBSDProcessListSimple(@PProcList);
    Le @ en Pascal correspond au & en C. Si bien que PProclist pointe sur l'adresse de la structure créée dans la fonction C. Côté C, ça se passe ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *proclistsimple = result;
    En fait au début je travaillais directement sur "*proclistsimple". Je suis passé par une variable supplémentaire "result" pour voir si ça ne résoudrait pas mes soucis, mais ça ne change rien.

    D'ailleurs, cela fonctionne puisque je récupère bien ma liste de processus dans mon programme Pascal. Donc mon PProclist pointe sur la structure. Mais c'est quand je souhaite libérer la mémoire que ça coince, donc uniquement ici

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cfun.ReleaseProcessListSimple(@PProcList);
    ce qui appelle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int ReleaseProcessListSimple(procsimple ** proclistsimple)
    {
    	procsimple *       result;
    	result = *proclistsimple;
    	free(result);
    	return 0;
    };
    Idem ici, mon premier code faisait directement un free sur "*proclistsimple". "result" est superflu.

    Je finis par douter de la possibilité de faire ce type d'opération, à savoir:
    1. Appel d'une fonction externe qui alloue et renvoie un pointeur
    2. Utilisation du pointeur pour accéder à la structure
    3. Appel d'une fonction externe qui désalloue la mémoire

    En tous cas, je sais que je ne peux pas désallouer dans ma fonction Pascal ce que ma fonction C a alloué. C'est pourquoi je passe par une fonction C qui est censée le faire.

Discussions similaires

  1. Désallocation mémoire dans une Dll
    Par alyma dans le forum C
    Réponses: 3
    Dernier message: 14/05/2013, 14h57
  2. Problème d'allocation mémoire dans un constructeur
    Par zaz83 dans le forum Débuter
    Réponses: 2
    Dernier message: 12/06/2009, 13h31
  3. Réponses: 2
    Dernier message: 05/09/2008, 11h18
  4. Réponses: 6
    Dernier message: 30/05/2007, 10h41
  5. Problème d'allocation de mémoire dans la pile
    Par prophet666 dans le forum x86 32-bits / 64-bits
    Réponses: 6
    Dernier message: 19/01/2006, 02h22

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