2009-07-17 3 views
0

J'ai cherché loin et large pour sa signification. Ma conjecture est que j'ai d'une manière ou d'une autre une pile corrompue. Je reçoisQu'est-ce que tiny_free_list_add_ptr?

minuscule _ free_ list_ add_ ptr

le 16 appel de la ligne qui dit:

NSDateFormatter *theFormatter = [[NSDateFormatter alloc] init]; 

Quelle est la cause du problème? Ai-je raison de penser que j'ai une pile corrompue?

- (NSString *)formatDate:(NSString *)uglyDate withFormat:(NSString *)theFormat { 

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSDateFormatter *theFormatter = [[NSDateFormatter alloc] init]; 
    [theFormatter setDateFormat:theFormat]; 

    NSDate *realDateUgly = [NSDate dateWithNaturalLanguageString:uglyDate]; 
    if (realDateUgly == nil) 
     realDateUgly = [NSDate dateWithString:uglyDate]; 

    NSString *prettyDate = [[NSString alloc] initWithString:[theFormatter stringFromDate:realDateUgly]]; 

    [pool drain]; 
    [pool release];  
    [theFormatter release]; 
    return prettyDate; 

} 

Répondre

2
  1. Je doute que vous avez besoin d'une piscine ici.
  2. Vous sur-relâchez la piscine. drain est le même que release en code non GC. (release est tout aussi redondant dans le code GC, car alors c'est un no-op.)
  3. Vous avez une fuite prettyDate. Vous êtes censé le libérer. (Bien sûr, cela ne fonctionnera pas avec la piscine autour d'elle, ce qui est une bonne raison de tuer ce pool.)

Une fois que vous passez en revue le Memory Management Programming Guide for Cocoa et résoudre vos problèmes de gestion de la mémoire, vous devez soit trouver le problème est résolu ou au moins être mieux en mesure de le retrouver.

Si le problème persiste après la correction de la gestion de la mémoire, veuillez modifier votre question pour inclure la trace complète de la pile.

+0

Merci pour votre réponse rapide. Je n'aurais pas dû passer aussi vite sur la section Autorelease. J'ai pris vos conseils et enlevé la piscine. En ce qui concerne pretty date, je l'ai changé à ceci: NSString * prettyDate = [theFormatter stringFromDate: realDateUgly]; Le problème n'est plus dans cette fonction, mais ailleurs. Je vais étudier le Guide de programmation de gestion de mémoire pour Cocoa. Merci encore. –

+0

En fait, encore une chose: j'aimerais toujours savoir ce qu'est tiny_free_list_add_ptr. Juste curieux. :) –

+0

Une fonction interne, vraisemblablement dans la machin malloc (en rapport avec la liste libre). –

0

Je suppose que vous plantez dans tiny_free_list_add_ptr. Si tel est le cas, tiny_free_list_add_ptr ressemble à une fonction utilisée par une implémentation de malloc pour suivre les blocs de mémoire sur le tas. Si le tas est corrompu, je m'attendrais à ce qu'une telle fonction plante.

Vous êtes probablement sur la libération de quelque chose (comme le pool de publication automatique que Peter a signalé) ici ou dans une autre méthode.

Vous devriez essayer de courir avec l'ensemble de variables d'environnement NSZombiesEnabled. Voir http://developer.apple.com/technotes/tn2004/tn2124.html#SECFOUNDATION

0

Je serais prêt à parier que le problème est le suivant:

[pool drain]; 
[pool release]; 

Dans une application non-GC, le drain 'se comporte' comme la libération. 'Behaves' est le mot utilisé dans la documentation, mais la documentation est un peu ambiguë quand vous devez être précis sur le plan de la précision de ce qui se passe quand -drain est appelé. Pour moi, au moins, «se comporte» permet un peu de marge de manœuvre, surtout si on compare à «drain est exactement le même que la libération», ce qui laisse beaucoup moins de place pour l'interprétation.

La raison pour laquelle je soulève cette question est «qu'advient-il du pool autorelease après que -drain est appelé? Je n'ai pas trouvé de réponse satisfaisante dans la documentation à cette question. À différents endroits, la documentation implique que lors de l'exécution en mode GC, -drain se comporte comme une «indication pour le système GC» et appelle objc_collect_if_needed(). Je n'ai rien trouvé qui indique explicitement qu'en mode GC, un pool d'autorelease auquel un message -drain a été envoyé n'est plus valide (c'est-à-dire quelque chose qui se comporte comme si un message de libération lui avait été envoyé). Rien que je n'ai pu trouver dans la documentation semble interdire expressément d'envoyer un objet instancié NSAutoreleasePool un message -drain plusieurs fois lors de l'exécution sous GC.La chose la plus proche que j'ai pu trouver était proche de la partie supérieure de la documentation de la classe NSAutoreleasePool: 'drainer un pool a finalement pour effet de le désallouer'. Cela fait peu pour nous aider ici, cependant. Le contexte à partir duquel cela a été pris n'est pas très clair quant à savoir si cela s'applique ou non au mode GC ou non GC. En tout cas, il est qualifié de «en fin de compte», ce qui par définition de dictionnaire pédant signifie «pas maintenant, mais finalement». Sans la qualification 'en fin de compte', il n'est pas ambigu de savoir si l'objet de groupe autorelease instancié a été libéré et, par induction, que l'envoi de messages supplémentaires à ce pointeur entraînera un comportement indéfini. Donc, puisque je ne peux pas pointer vers quelque chose d'autorité pour sauvegarder cela, je suis d'avis que -drain, en mode non-GC, se comporte exactement comme -release (très probablement implémenté en interne comme [auto-release]). Si cela est vrai, vous avez 'over released' l'objet NSAutoreleasePool, auquel cas le problème disparaîtra si vous commentez l'une des deux instructions.

+0

Très approfondie. J'aime ça. –