Leaks of memory

saukeguysaukeguy Membre
mai 2012 modifié dans Objective-C, Swift, C, C++ #1
Bonjour a tous je travaille actuellement sur un projet XCode avec Objective C.



J'essaye de rendre mon programe dès le depart le plus lisible possible et sans fuite de mémoire ou probléme d'allocation.



Premierement j'ai utilisé clang afin d'identifir mes fuites mémoires et de les résoudre sur celui-ci je n'en est plus aucune. J'ai donc ensuite lancé mon programme via leaks mais celui-ci continue à  afficher une fuite mémoire de type appkit et une d'un autre type dont je n'arrive pas à  la résoudre.



Voici mon code :



Ne faites surtout pas attention au nommage des méthode qui comporte des majuscules ni au commentaire qui des fois sont en franglais, tout ceux- ci sera remanié dès que j'aurais résolu ce problème.



Dans ce fichier j'ai créer des méthodes qui vont me permettre d'ajouter, modifier,supprimer ou bien selectionner des champs dans une d mes base de données.



Voici souligner en rouge les erreur d'allocations que leaks prend en compte ainsi que d'autre erreurs de type NCFString de l'appkit apple et je ne sait pas pourquoi. Pourtant clang persiste et ne me donne aucune fuite mémoire.



methode_sql.m
<br />
//<br />
//  valorisation_sql.m<br />
//  projet_adit<br />
//<br />
//  Created by Reims_04 on 25/04/12.<br />
//  Copyright 2012 ADIT Champagne-Ardenne. All rights reserved.<br />
//<br />
#import &quot;methode_sql.h&quot;<br />
@implementation methode_sql<br />
<br />
//Initialisation du path de l&#39;une des bdd<br />
-(void) initBDDPath:(int) numBDD{<br />
//Nom de la base de données<br />
if(numBDD==1)<br />
  databaseName = @&quot;/projet_adit/valorisation&quot;;<br />
else if(numBDD==2)<br />
{<br />
  databaseName = @&quot;/projet_adit/main&quot;;<br />
}<br />
else if(numBDD==3)<br />
{<br />
  databaseName = @&quot;/projet_adit/questionnaire&quot;;<br />
}<br />
// Obtenir le chemins complet de la base de donées<br />
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);<br />
NSString *documentsDir = [documentPaths objectAtIndex:0];<br />
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];<br />
/*Voici  le probleme d&#39;après XCode leaks*/<br />
<br />
[color=#ff0000]result = [[[NSString alloc]init]autorelease];<br />
aatier = [[[NSMutableDictionary alloc]init]autorelease];<br />
//Methode general de navigation de boite de dialogue et d&#39;attribution d&#39;une plage de date pour les NSDatePicker<br />
pool = [[general_methode alloc]init];[/color]<br />
<br />
}<br />
<br />
-(void) dealloc{<br />
[pool release];<br />
[super dealloc];<br />
}<br />
<br />
<br />




Comme je l'aidit précédemment aucun problème au niveau de clang mais au niveau de leaks c'est une autre histoire. Merci de vos futurs réponses si je fait nimporte quoi sur ce coe s'il vous plaà®t de me lsignaler et de me donner des elements afin de m'améliorer. Désoler du surplus d'informations et je tiens a préciser que la fuite mémoire apparait quand je fait plusieurs fois la même opération et jamais au premier clique.



Merci d'avance pour vos futurs réponses

Réponses

  • CéroceCéroce Membre, Modérateur
    Euh, ça fait beaucoup pour nous. Franchement, je veux bien aider, mais là , tu nous balances un gros bloc de code en nous demandant "Où sont les fuites"?



    Puisque des fuites ont été détectées, dis-nous où.
  • Alf1996Alf1996 Membre
    mai 2012 modifié #3
    Waouh, j'ai commencé à  lire et je me suis arrêtée après une cinquantaine de lignes...

    Aurais tu une petite copie d'écran de ce que te donne Instruments/leaks? Parce que là , comme dit Ceroce, on veut bien aider, mais on ne vas pas pouvoir regarder tout ton code ! image/wink.png' class='bbc_emoticon' alt=';)' />



    à‰dit :

    http://forum.cocoacafe.fr/forum/17-presentation-des-membres/
  • LarmeLarme Membre
    mai 2012 modifié #4
    Pas d'présentation ?



    Bizarre, ça n'a pas l'air d'être le même code que sur MacGé, enfin y'a methode_sql.m et pas d'autres...
  • Désoler pour tous le code j'ai essayez d'alléger.
  • Alf1996Alf1996 Membre
    mai 2012 modifié #6
    result et aatier en autorelease ?

    Qu'est ce que tu fais ensuite avec ces variables ?



    Et n'oublie pas d'aller te présenter...
  • 'Larme' a écrit:


    Pas d'présentation ?



    Bizarre, ça n'a pas l'air d'être le même code que sur MacGé, enfin y'a methode_sql.m et pas d'autres...




    Ah oui... T'as pas eu ta réponse sur MacGe... Alors tu essayes ici ?!!!
  • saukeguysaukeguy Membre
    mai 2012 modifié #8
    aatier me est un dictionnaire que je retourne lors de l'appelle d'une de mes fonctions de selection d'enregistrements qui me renvoie un dictionnaire avec les élements choisit dans la requete SQL. Ce dictionnaire est enfin retourné lors de l'apelle de cette méthode.



    Result quand a lui me permet de retourner un châine de caractère qui correspond au format de la requete de base de que je veut lorsque je fait la même selection. Pourquoi je ne devrais pas les mettre en autorelease? Puisque toutes les deux sont des variables de renvoies je ne sait donc pas eactement quand les détruire??



    Oui c'est bien évident, j'essaye de me débrouiller. Le problème est que sur mac génération on ma traité, pourtant je suis de bonne fois et j'essaye de lire un peu tout ce qu'on me donne mais aucun réponse me convenant ne m'a était donné . Mais de la a dire que j'ai fait du copier/ coller de code. Il est vrai que je me suis inspiré dun code existant mais celui- ci je l'ai réalisé en son intégralité.
  • Ok je me posais juste la question de ce que tu en faisais après ; puisque tu dis que la fuite semble venir de là ...
  • saukeguysaukeguy Membre
    mai 2012 modifié #10
    Voici les deux imprim écrans de Xcode lorsque j'ajoute un objet a deux reprise la fuite mémoire apparaà®t et non avant. Je précise que j'utilise XCode 3.2 si ca a une incidence.

    <br />
    NSMutableDictionary *tab_objet = [sqlManager SelectElementToTable:array:select:from:where:1];<br />
    
  • CéroceCéroce Membre, Modérateur
    mai 2012 modifié #11
    Voyons, voyons:


    <br />
    -(void) initBDDPath:(int) numBDD{<br />
    




    Les méthodes d'init ne s'écrivent jamais ainsi. Il faut utiliser la forme idiomatique:
    <br />
    - (id)init<br />
    {<br />
    	self = [super init];<br />
    	if (self) {<br />
    	  <br />
    	}<br />
    	return self;<br />
    }<br />
    




    Ensuite, la méthode s'appelle initWithBDDPath:, alors on attend une NSString comme argument puisqu'un chemin de fichier est stocké dans une NSString.


    <br />
    if(numBDD==1)<br />
      databaseName = @&quot;/projet_adit/valorisation&quot;;<br />
    else if(numBDD==2)<br />
    {<br />
      databaseName = @&quot;/projet_adit/main&quot;;<br />
    }<br />
    else if(numBDD==3)<br />
    {<br />
      databaseName = @&quot;/projet_adit/questionnaire&quot;;<br />
    }<br />
    




    Utiliser des constantes en dur (==1) est une mauvaise idée. Regarde sur le net comment déclarer des énumérations en C (mot clé enum). Regarde aussi switch... case pendant que tu y es.


    <br />
    databasePath = [documentsDir stringByAppendingPathComponent:databaseName];<br />
    


    -[NSString stringByAppendingPathComponent:], comme toutes les méthodes dont le nom ne commence pas par alloc, init, new ou copy, renvoie un objet autoreleasé.

    De fait, il va disparaà®tre au prochain cycle, et il est anormal de le stocker dans une variable d'instance. databasePath pointera à  la fin du cycle sur un objet qui n'existera plus.


    <br />
    result = [[[NSString alloc]init]autorelease];<br />
    


    Une NSString n'est pas modifiable. Ce code ne sert donc à  rien, mais il crée une fuite, pour la même raison que ci-dessus: une variable d'instance pointe sur un objet autoreleasé.


    <br />
    aatier = [[[NSMutableDictionary alloc]init]autorelease];<br />
    


    Même erreur.


    <br />
    pool = [[general_methode alloc]init];<br />
    




    pool, c'est pas terrible comme nom, parce que ça évoque l'autorelease pool.





    P.S.: L'ambiance est à  chier sur le forum de dev de MacGé. Et puis, j'en ai marre de répondre à  des gens pas sérieux.
  • Merci beaucoup c'est super gentil de ta part de m'avoir donner tous ces éléments de réponses, je ne demandais rien de plus qu'une simple réponse comme celle-ci au lieu de critiques. je vais me pencher sur les différents points listé et essayer de remanier mon code afin d'éviter cette fuite mémoire. Mais est-ce normal qu'ue fuite mémoire ne se déclare pas au premiere événement mais qu'au deuxième??
  • 'Céroce' a écrit:


    P.S.: L'ambiance est à  chier sur le forum de dev de MacGé. Et puis, j'en ai marre de répondre à  des gens pas sérieux.




    C'est vrai... Quelle ambiance !!!
  • CéroceCéroce Membre, Modérateur
    'saukeguy' a écrit:


    Mais est-ce normal qu'ue fuite mémoire ne se déclare pas au premiere événement mais qu'au deuxième??




    Oui, [url="http://www.cocoa.fr/tag-mémoire/"]parce que l'autorelease pool a un fonctionnement cyclique[/url].
  • Oh le con mais bien sur !! Merci encore et super bien expliquer ton site!!
  • saukeguysaukeguy Membre
    mai 2012 modifié #16
    C'est bon toute mes fuites mémoire on était trouver et modifier. Seul hic sur ce nswidowcontroller que je ne sait jamais quand désallouer..


    <br />
    -(void) navigation:(NSString*)xibName:(NSWindow*)window{<br />
        <br />
        controller = [[NSWindowController alloc]<br />
                      initWithWindowNibName:xibName];<br />
        <br />
        if(window.isZoomed)<br />
        {<br />
            [controller.window performZoom:window] ;<br />
        }<br />
        <br />
        [controller showWindow:self];<br />
        [window performClose:self];<br />
        <br />
    }<br />
    




    mais je suppose que la methode initWithWindowNibName est ue methode de classe donc automatiuement autoreleasé non?
  • 'saukeguy' a écrit:


    C'est bon toute mes fuites mémoire on était trouver et modifier




    Bien !

    Maintenant, seconde phase, trouver et corriger les fôtes d'orthographe...
  • Comme je l'ai dit plus aucune erreur ni sur clang ni sur XCode au niveau de mon code mais une seul fuite apparait au moment de l'ajout dans ma base de donnée, je croit qu'il est en liaison avec mon outlet de type textfield, est-ce possible?



  • Oui .. ARC !
  • Je le répète, je n'ai aucune envie d'utiliser ARC et je ne le peut pas puisque je suis sous la version XCode 3.2 et il faut une version récente ce qui nécessite un upgrade vers Lion.
  • LeChatNoirLeChatNoir Membre, Modérateur
    Non, ARC, tu peux l'utiliser avec Snow Leoprad et XCode 4.2
  • LeChatNoirLeChatNoir Membre, Modérateur
    mai 2012 modifié #22
    ARC, tu peux l'utiliser avec XCode 4.2 et Snow Leopard... Oups désolé....
  • saukeguysaukeguy Membre
    mai 2012 modifié #23
    XCode 4.2 sous snow Leopard? Pourtant j'avais essayé de l'installer mais une erreur de version qui n'été pas assez récente se produisait.



    Bon et bien je n'arrive pas a résoudre cette fuite mémoire qui d'après ce que j'ai compris ne se produit que lorsqu'il y utilisation de NSTextField. Est-ce un bug non corriger de Apple puisque j'utilise la version 3.2 de XCode ou bien est-ce autre chose? Si quelqu'un a ou a eu le même problème, merci de me le signaler.


    <br />
    <br />
    [color=#7340a3]NSString[/color] *nom_objet_recup = [[[color=#7340a3]NSString[/color] [color=#3f217c]alloc[/color]][color=#3f217c]initWithString[/color]:[[color=#4b8186]nom_objet[/color] [color=#3f217c]stringValue[/color]]];<br />
    


    Voici comment je récupère la chaà®ne de caractère saisie. Je release bien évidemment le NSString à  la fin de ma méthode.



    Cela fait deux jour que je suis penché dessus et ça ne m'avance guère. Si certains on une piste.
  • DrakenDraken Membre
    mai 2012 modifié #24
    Xcode 4.2 tourne trés bien sur un Mac avec Snow Leopard. Heureusement d'ailleurs, mon vieux Mac Mini n'a qu'un Go de RAM et ne supportera jamais Lion.
  • zoczoc Membre
    'saukeguy' a écrit:


    je suppose que la methode initWithWindowNibName est ue methode de classe donc automatiuement autoreleasé non?


    Certainement pas.



    Tout d'abord initWithWindowNibName n'est pas une méthode de classe, mais une méthode d'instance: Elle est exécutée sur l'instance crée par la méthode de classe alloc.



    Ensuite, les conventions de nommage, qui font loi dans la gestion mémoire (revoir la documentation adéquate), précisent bien que les méthodes commençant par "init" (entre autre) effectuent un transfert de propriété de l'objet retourné à  l'appelant. Par conséquent, l'objet retourné n'est pas "autoreleasé".



    Quoi qu'il en soit, le fait qu'une méthode soit ou non une méthode de classe ne change en rien la convention de nommage. Donc une méthode de classe dont le nom commençerait par "init" ne retournerait pas non plus d'objet autoreleasé.
Connectez-vous ou Inscrivez-vous pour répondre.