Fuites ou pas de fuites?

tabliertablier Membre
On en a parlé souvent, mais j'ai parfois de gros doutes. Voici un extrait d'un source trouvé sur le web:
- (void)déclaration  {

................................ etc
NSData *dataRecu = [UnFicher readDataToEndOfFile] ;
................................ etc
NSString *ptrManuel = [NSString alloc] initWithData:dataRecu encoding:NSASCIIStringEncoding] autorelease];<br /> [color=green]//remove EOF[/color]<br /> ptrManuel = [ptrManuel substringToIndex:[pathToManual length] [color=blue]-1[/color;
//To get just the last line of the output in case fortune or other programs that output data during login are installed
ptrManuel = ptrManuel componentsSeparatedByString: [color=red]@&quot;&#092;n&quot;[/color lastObject] ;
//make sure it starts with a / otherwise make nil
if (![ptrManuel hasPrefix:@/])
ptrManuel = nil;
................................ etc
}
J'ai l'impression que cette utilisation de "ptrManuel" doit générer des fuites de mémoire.
Est-ce que je me trompe??

Réponses

  • mpergandmpergand Membre
    11:04 modifié #2
    A première vue, pas de fuites de mémoire.
  • tabliertablier Membre
    11:04 modifié #3
      :(  Alors il y a quelque chose je n'ai pas compris!
    La première allocation, pas de problème -> une zone dans l'auto-release pool .
    Mais en suivant, "[ptrManuel substringToIndex:[pathToManual length] -1]" renvoie un nouveau string qui sera pointé par "ptrManuel".
    Comme la zone est alloué sous "autoRelease" et que "ptrManuel" est toujours en usage, cette zone ne sera pas dés-allouée et je ne vois pas pourquoi le nouveau string serait placé dans cette zone!
    Et en suivant toujours, à  chaque nouveau changement du pointeur "ptrManuel" je ne vois pas pourquoi la zone mémoire précédente serait dés-allouée ou pourquoi le nouveau string serait mis dans la zone allouée du string précédent.
    Normalement un NSString n'est pas "mutable", ce qui me semble est contre dit par ce code s'il n'y a pas de fuite mémoire. J'ai beau lire la doc, ça ne me parait pas évident!
  • CéroceCéroce Membre, Modérateur
    novembre 2010 modifié #4
    Je ne suis pas sûr que tu aies bien compris ce que fait -[autorelease]: le pointeur sur l'objet est placé dans l'autorelease pool. L'objet sera désalloué lorsque le pool sera vidé (habituellement à  la fin de la boucle d'événements).

    Peu importe que ton code conserve une référence sur l'objet ou pas.


    Les méthodes -[substringToIndex:] et -[componentsSeparatedByString] renvoient des NSStrings autoreleasées. On le sait pas convention: leur noms ne commencent pas par alloc, create, new ou copy.
  • tabliertablier Membre
    11:04 modifié #5
    Je ne suis pas sûr que tu aies bien compris ce que fait -[autorelease]
        :P  Exact, et c'est pour cela que je pose des questions. Bon, avec l'explication, je crois que j'ai compris. Les objets créés ici sont mis dans le pool (convention de nom) et seront dès-alloués d'office en fin de boucle d'évènement. Ce qui me semble curieux, c'est que le pointeur lui-même soit aussi dans le pool puisqu'il est local à  la méthode et devrait disparaitre lorsqu'elle retourne. En objective-C il n'y a pas de pile pour les variables locales?

  • mpergandmpergand Membre
    novembre 2010 modifié #6
    Effectivement en retour de méthode l'emplacement réservé pour le pointeur disparaà®t de la pile, mais la valeur de ce pointeur a été mémorisée par le ReleasePool.
    Donc, pas de prob  :)

    C'est comme si je faisais:
    <br />NSString* sauveA;&nbsp;  // variable globale<br />....<br /><br />-(void) blabla<br />{<br />NSString* A=@&quot;A&quot;;<br />sauveA=A;<br />A=@&quot;B&quot;;&nbsp;  // A pointe vers @&quot;B&quot; et sauveA pointe vers @&quot;A&quot;<br />}<br />
    

  • CéroceCéroce Membre, Modérateur
    11:04 modifié #7
    dans 1289402135:

    Ce qui me semble curieux, c'est que le pointeur lui-même soit aussi dans le pool puisqu'il est local à  la méthode et devrait disparaitre lorsqu'elle retourne. En objective-C il n'y a pas de pile pour les variables locales?


    Je vais te parler en termes d'électronicien, tu vas mieux comprendre, parce que tu confonds deux choses:
    - le pointeur, qui est une adresse1: par exemple, la NSString est stockée à  partir de l'adresse 0x1000
    - le stockage du pointeur: ça peut être une case mémoire sur la pile (habituel sur 0x86), mais aussi un registre d'adresses (habituel sur PowerPC).
    Quand on quitte le sous-programme, la pile est dépilée, mais la NSString est toujours en 0x1000. Ce qu'on a passé à  l'autorelease pool est cette adresse 0x1000: il sait qu'il devra libérer l'objet qui s'y trouve.

    1 En fait, sous les ordinateurs modernes pas tout à  fait, il y a une conversion d'adresse qui est effectée par la MMU pour convertir l'adresse "processus" en adresse absolue.
  • AliGatorAliGator Membre, Modérateur
    11:04 modifié #8
    Disons que tu confonds la laisse et le chien.
    L'objet (= le chien) est mis dans l'autorelease pool, que tu aies ou non un pointeur dessus.
    La variable "ptrManuel" (= la laisse) te permet d'accéder à  l'objet pour le manipuler, mais ce n'est pas l'objet lui-même.

    Tu peux avoir plusieurs variables qui pointent sur le même objet, il n'y aura quand même qu'un seul objet.
    TU peux également avoir créé un objet mais n'avoir plus aucune variable pointant dessus.
  • tabliertablier Membre
    11:04 modifié #9
    Je ne pense pas que je confonde la laisse et le chien. Pour reprendre cette analogie, la laisse est aussi un objet dont la fonction est de retenir le chien (même si c'est un objet C et pas Objective-C). Quand j'écris: NSObject *lobjet, je comprends parfaitement que lobjet est un objet pointeur. Probablement un long ou un long long, dont le contenu est une valeur représentant l'adresse de la structure d'un NSObject (s'il a été créé!).
    Ce que je voulais savoir c'est, si comme en C je déclare dans une méthode NSObject *lobjet; est-ce que l'objet pointeur "lobjet" est mis sur la pile et disparait quand la méthode retourne ou bien est-ce que cet objet pointeur est mis dans le pool et disparaitra en fin de boucle d'évènement. Du moins pour le principe et sans tenir compte de la mémoire virtuelle.
    Serais-je plus clair comme cela?
  • mpergandmpergand Membre
    novembre 2010 modifié #10
    Une fois compilé, un prog en ObjC est du pur C.

    Par conséquent, l'objet pointeur le pointeur d'objet local à  la méthode est dans la pile comme en C. (ou dans un registre, on peut déclarer explicitement: register NSObject* lobject )
    C'est l'instruction [lObjet autorelease] que enregistre la valeur de ce pointeur dans l'autoreleasePool.

  • CéroceCéroce Membre, Modérateur
    11:04 modifié #11
    C'est ce terme d'objet pointeur qui nous gêne.
    Un objet est vraiment quelque chose de précis (entité avec des variables d'instance et des méthodes). Dans certains langages, tout est objet, mais en ObjC, les pointeurs sont des types primitifs comme le sont les int, float ou autre char.
  • iLandesiLandes Membre
    11:04 modifié #12
    Petite citation issue de "Programmation iPhone OS3" de Thomas Sarlandie aux éditions Eyrolles.
    Chapitre 2 : L'essentiel d'objective-C / Règle de gestion de la mémoire en Objective-C


    Vous devenez propriétaire des objets que vous avez créés en utilisant une méthode dont le nom commence par alloc, new ou contient copy. Vous devenez également propriétaire des objets que vous retenez. Vous devez libérer la mémoire des objets que vous détenez en appelant la méthode release ou autorelease. Dans les autres cas vous ne devez jamais les appeler.

    Conseil : Relisez trois fois le paragraphe ci-dessus


    Personnellement ce petit paragraphe m'a bien aidé à  comprendre la gestion mémoire, moi qui ne vient pas de la poo. Par pudeur je ne citerai qu'un seul langage pré-historique que l'on ma enseigné en BTS à  l'époque : le COmmon Business Oriented Language ou COBOL ; spéciale dédicace aux Cromagnons du Forum.

    Cordialement
  • tabliertablier Membre
    11:04 modifié #13
    @ seb@stien
    Je n'ai ni Ipad  ni iPhone donc je n'ai pas ce bouquin et je ne pense pas acheter un de ces machins un jour. Enfin, merci pour l'info.

    @Céroce
    C'est ce terme d'objet pointeur qui nous gêne.
    C'était juste un peu de provocation. D'ailleurs j'ai indiqué qu'un pointeur devait être un long ou un long long (qui sont des types primitifs).
  • AntilogAntilog Membre
    11:04 modifié #14
    dans 1289469850:

    []
    Personnellement ce petit paragraphe m'a bien aidé à  comprendre la gestion mémoire, moi qui ne vient pas de la poo. Par pudeur je ne citerai qu'un seul langage pré-historique que l'on ma enseigné en BTS à  l'époque : le COmmon Business Oriented Language ou COBOL ; spéciale dédicace aux Cromagnons du Forum.

    Cordialement


    Merci pour lui!  :'(
    PS: Le Cobol n'est pas mort, je le côtoie tous les jours!
Connectez-vous ou Inscrivez-vous pour répondre.