Home FAQ Debuging Was bedeutet der Fehler "malloc: *** error for object 0xXXXXXXX: pointer being freed was not allocated"?

iPhone Gewinnspiel

Was bedeutet der Fehler "malloc: *** error for object 0xXXXXXXX: pointer being freed was not allocated"? PDF Drucken E-Mail
Share
Geschrieben von: Philipp   
WEDNESDAY, 28 OCTOBER 2009 15:41
FRAGE:
Was bedeutet der Fehler "malloc: *** error for object 0xXXXXXXX: pointer being freed was not allocated" ?

ANTWORT:
Oftmals bekomt man auf der Konsole von Xcode genau diese Meldung, wenn versucht wird ein Objekt mit free oder delete wieder freizugeben. Genau bedeutet diese Fehler Meldung, das das Objekt an der Adresse 0xXXXXXXX freigegeben werden soll, obwohl es vorher gar nicht alloziiert worden war. Viele Programmierer ignorieren diese Fehlermeldung, da das Programm meist ohne Absturz weiter läuft. Dies kann sich jedoch im Nachhinnein als schwerer Fehler herausstellen. Aus diesem Grund empfehle ich die Stelle im Code zu finden, an der das Objekt freigegeben wird um dann den Fehler zu beheben.

Um die betreffende Codestelle zu finden, gibt es einen zwar relativ aufwendingen aber erfolgreichen Weg, welchen ich nun erkären werde. Bitte beachtet jedoch, das Ihr das folgende Beispiel nur auf dem iPhone-Simulator ausführen könnt und das Ihr die beschriebenen Projektänderungen nur für das Debug-Release macht.

Wer das Xcode-SDK installiert hat, hat auch gleichzeitig einige Kommandozeilenwerkzeuge installiert bekommen, u.a. die Tools malloc, heap, vmmap und malloc_history. Letzteres, also malloc_history ist jenes, welches wir benötigen um den Fehler im Code zu finden. (Diese Tools selber, werden übriegens von der Instruments Applikation benutzt, um für euch die Analysen durchführen zu können.)

Um nun aber malloc_history benutzen zu können, bedarf es einer kleinen Änderung am Xcode-Projekt selbst. Ihr müsst nämlich noch besondere Debug-Informationen einschalten. Öffnet dazu in eurem Projektbaum (also unterhalb von Groups&Files) den Knoten "Executables" und klickt dann doppelt auf dortigen Eintrag (das sollte der Projektname sein):



Es öffnet sich nun das Info-Fenster zu eurem Executable, geht dort auf den Reiter "Arguments" und tragt unterhalb von "Variables to be set in the environment" folgende Umgebungsvariablen ein (als value muss jeweils YES genommen werden):
  • NSDebugEnabled
  • MallocStackLogging
  • MallocStackLoggingNoCompact
Das Ganze sollte bei Euch nun so aussehen:

Das war es an Änderungen für das Projekt. Der nächste Schritt wäre es, Euer Programm nun im Debug-Mode zu starten. Also achtet darauf das Ihr für den iPhone-Simulator baut und dann klickt bitte Run->Debug. Wenn Ihr alles richtig gemacht habe, sehr Ihr in der Konsole von Xcode nun etwas wie das folgende:

HelloWorld(15911) malloc: stack logs being written into /tmp/stack-logs.15911.HelloWorld.JRskfY

Merkt euch bitte die Zahl in den Klammern (im Beispiel die 15911). Das ist die Prozes-ID, welche wir später benötigen. Die zusätzlichen Debug-Informationen werden nun also in die Datei /tmp/stack-logs.15911.HelloWorld.JRskfY gelogt.
Führt nun eure iPhone Applikation so weit aus, bis der Fehler "malloc: *** error for object 0xXXXXXXX: pointer being freed was not allocated" in der Xcode-Konsole auftritt und merkt euch dann auch die Speicheradresse die angegeben wird.

Kommen wir nun zurück zu malloc_history. Öffnet dazu das Terminal Programm auf eurem Mac OS X (/Programme/Terminal.app). malloc_history hat folgende syntax
 malloc_history pid address

Also müsst ihr
 malloc_history 15911 0xXXXXXX

eingeben in den Terminal eingeben. (15911 ist die Prozess-ID und 0xXXXXXX müsst ihr natürlich durch die Adresse aus eurer Fehlermeldung ersetzen).
Bestätigt das ganze mit ENTER und siehe da, nach einigen Sekunden seht Ihr den Stackverlauf der aufgerufenen Funktionen um an die Stelle zu kommen, an welcher der Fehler auftritt. So ziemlich der letzte Eintrag ist die Funktion, in welcher bei euch der Fehler entsteht. Hier einmal ein Beispiel (die Funktion, in welcher der Fehler auftritt habe ich fett hervorgehoben):

Call [4] [arg=0]: thread_a0070720 |start | main | UIApplicationMain | -[UIApplication _run] | GSEventRun | GSEventRunModal | CFRunLoopRunInMode | CFRunLoopRunSpecific | CATransactionTimerCallback | run_animation_callbacks | -[UIViewAnimationState animationDidStop:finished:] | -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] | -[MPFullScreenVideoViewController _hideOverlayAnimationFinished:] | -[MPMoviePlayerController _playerFinishAndFadeOut] | -[NSNotificationCenter postNotificationName:object:userInfo:] | _CFXNotificationPostNotification | __CFXNotificationPost | _nsnote_callback | -[MovieView reinitMediaManager] | MediaManager::reinit() | MediaManager::initAudioPlayer() | MediaManager::ReleaseAudioPlayer() | free | malloc_zone_free

Ihr müsst nun also bei euch gucken, wo ihr in der gefunden Funktion ein delete oder free aufruft und überlegen ob es an dieser Stelle richtig oder sinnvoll ist.



Kommentare (1)
danke
1 TUESDAY, 29 JUNE 2010 12:58
???
danke für die info - ist sehr hilfreich..

Ihren Kommentar hinzufügen

Ihr Name:
Ihre Webseite:
Betreff:
Kommentar:
  Bild, welches den Sicherheitscode enthält
Sicherheitscode:
LAST_UPDATED2