2016-04-27 22 views
2

Kann mir bitte jemand helfen, herauszufinden, warum der "nächste" Zeiger in meiner verknüpften Liste auf den falschen Speicheradresse im Code auf 32 dereferenziert -Bit-Plattform, funktioniert aber gut auf 64-Bit-Plattform? Mein Programm ist als universelle Binärdatei auf Xcode 7.3 erstellt und in C++ geschrieben.Warum ist meine verknüpfte Liste "nächste" Zeiger Dereferenzierung in den falschen Speicher (XCode, C++)

Ich habe eine verkettete Liste und Dereferenzierung der "nächsten" Zeiger im Debugger zeigt den richtigen Speicher, aber Dereferenzierung in Code liest den Speicher, der 4 Bytes jenseits ist, wo es lesen sollte. Ich werde versuchen, zu erklären.

Die Objekte auf der Liste sind 4144 Bytes jeder, die letzten 4-Bytes sind ein 32-Bit-Zeiger auf das "nächste" Element auf der Liste. Wenn wir auf den "nächsten" Zeiger im Speicher (0xBFFD63AC) schauen, sehen wir, dass es 4 Nullen (NULL) sind, das ist korrekt. Beachten Sie jedoch, dass der Speicher bei 0xBFFD63B0 ein 0x01 ist. Dies ist das Byte nach dem "nächsten" Zeiger. Wenn ich den Debugger fragen die nächste Variable zu drucken, druckt er den richtigen Wert (NULL):

(lldb) print l_pObject->Next 
(Object__t *) $0 = 0x00000000 
(lldb) memory read &(l_pObject->Next) 
0xbffd63ac: 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................ 

Allerdings, wenn ich den Code ausführen, der die „next“ Zeiger dereferenziert, liest die Daten tatsächlich von 0xBFFD63B0 statt von 0xBFFD63AC:

l_pObject = l_pObject->Next; 

(lldb) print l_pObject 
(Object_t *) $3 = 0x00000001 
(lldb) memory read &(l_pObject) 
0xbffd2504: 01 00 00 00 80 53 fd bf 00 00 00 00 6c 82 2e 

ich bin sicher, es die 0x01 von 0xBFFD63B0 liest. Der Debugger scheint zu wissen, dass "next" den Speicher bei 0xBFFD63AC anzeigt, aber aus irgendeinem Grund liest Dereferenzierung "next" im Code tatsächlich von 0xBFFD63B0, aber ich bin mir nicht sicher, wie ich herausfinden soll, warum. Ich habe versucht, der Struktur __attribute__((packed)) hinzuzufügen, aber das machte keinen Unterschied. Es ist schwierig festzustellen, wo etwas schief läuft, weil der Debugger mir etwas anderes sagt, als was wirklich passiert. Irgendwelche Tipps, wie Sie von hier aus fortfahren, würden sehr geschätzt werden!

EDITED MEHR INFO hinzuzufügen:

In den am wenigsten gibt es einen hier Debugger Fehler! Ich frage den Debugger, um die Größe der Struktur zu drucken, und es gibt mir 4144, aber im Code verwende ich die C-Funktion sizeof() und das gibt mir 4148! Es passiert also definitiv ein Padding in der Struktur, aber der Debugger und anscheinend dieser Codeabschnitt sind blind dafür. Dies ist die Wurzel meines Problems.

Debugger:

(lldb) print sizeof(*l_pObject) 

(unsigned long) $ 0 = 4144

Code:

unsigned int iSizeOf = sizeof(*l_pObject); /* iSizeOf will equal 4148! */ 

Etwas lustig passiert ...

Antwort

0

Ohne den Code zu sehen, es ist unmöglich zu sagen. Im Allgemeinen neigen Zeiger jedoch dazu, bei 64-Bit-Systemen 8 Byte und bei 32-Bit-Systemen 4 Bit breit zu sein. Offensichtlich haben Sie beobachtet, dass es 4 Bytes weit darüber hinaus springt, wo es sein sollte, was ein starker Indikator ist. (0xBFFD63B0 - 0xBFFD63AC) == 4.

+0

Ich würde den gesamten Code veröffentlichen, wenn ich könnte, aber es ist wahrscheinlich 50 + Dateien und Zehntausende von Zeilen. ABER ich habe einen Teil davon gefunden, was meine Kopfschmerzen verursacht! Der Debugger lügt. Ich habe meinen ursprünglichen Post oben bearbeitet, um ihn zu zeigen. – Matt

0

OK Ich fand das Problem, ich hätte es sofort erkannt. Der Code, der abstürzte, befindet sich in einer Bibliothek. Sowohl die Bibliothek als auch die aufrufende Anwendung teilen Definitionen für Variablentypen. Aufgrund eines fehlenden Präprozessorflags auf der Anwendungsseite wurde einer dieser Typen auf der Anwendungsseite 4 Byte kleiner zugewiesen als im Bibliothekscode. Wenn also die Anwendung eine verknüpfte Liste von Objekten erstellte und eine Referenz an die Bibliothek übergab, war jedes Objekt in dieser Liste 4 Byte kleiner als die Bibliothek es erwartet hatte.Was es weniger offensichtlich machte, war der Debugger zeigte mir Adressen und Offsets basierend auf was in der Anwendung zugewiesen wurde, so schien auf den ersten Blick alles richtig dimensioniert zu sein. Ich entschied, dem Debugger nicht zu vertrauen und schrieb meinen eigenen Code, um Adressen und Offsets zu überprüfen, und dann wurde es offensichtlich, was passierte. Wie auch immer, lange Rede kurzer Sinn, stellen Sie sicher, dass Ihre Anwendung und die Bibliothek Typen zuweisen, um die gleiche Größe zu haben, und dann werden die Dinge viel besser funktionieren. :)