Hallo,
ich habe eine Überlauf und bekomme den nicht weg.
Mein Programm ist ca. 1000 Zeilen groß. Allerdings läuft das Programm
nicht lange, nach wenigen Funktionen ist schluss.
Ich habe alle malloc()'s wieder ge-free()'d. Das sind auch nur kleine
malloc()'s von höchstens 20Byte, und auch nur wenige an der Zahl.
Hier ein bißchen Code, was passiert:
1
NODEglobal_node;
2
3
voidrotz(){
4
5
NODE*local_node;
6
7
local_node=&global_node;
8
9
printf("globus %x locus %x, &global_node,local_node);
Beim ersten Mal geht noch alles gut. Nach einer Zeit rufe ich die
Funktion wieder auf, und die Ausgaben der Adresse von locus ist für'n
Lokus.
Die Adresse von global_node stimmt hingegen immer noch.
Die Adresse von local_node ist ganz klein ( 0x20), während die von
global_node groß ist, 0x453453 (oder so).
Also, Überlauf, oder?
Aber am Heap kann's nicht liegen. Egal ob der "nur" 0x400 Byte oder
0x5'000
Byte groß ist. Immer spinnt der an der selben Stelle. Auch die
Stack-Größe ändern bringt nichts.
Tja, ich weiß nicht weiter. Ich sitze schon seit sieben Stunden daran.
Mein Projekt:
Xilinx
Microblaze
BRAM 0x10'000
Standalone oder Xilkernel ( beides gleicher Fehler)
C-Code
Na gut, werde gucken;
aber kann das wirklich sein?
Da läuft kein Thread oder so, sondern alles schön iterativ. Und die
beiden Zeilen stehen direkt untereinander. Wie kann denn eine Zuweisung
schiefgehen?
1
local_node=&global_node;
2
printf("globus %x locus %x",&global_node,local_node);
olpo schrieb:> Da läuft kein Thread oder so, sondern alles schön iterativ. Und die> beiden Zeilen stehen direkt untereinander. Wie kann denn eine Zuweisung> schiefgehen?
Dein eigentliches Problem sitzt ganz woanders.
Was du siehst sind die Symptome, aber nicht die Ursachen.
local_node = &global_node;
printf("globus %x locus %x, &global_node,local_node);
Eigentlich müßten ja beide Werte gleich sein. Denkbar, daß %x auf
dem System eben nicht der Wert des kompletten Pointers ist.
Außerdem fehlt ein Hühnerfuß, das kann so nicht mal kompiliert werden.
Kann es sein, dass .text zur Laufzeit überläuft?
Wenn ja, wie kann ich die Größe von .text ändern? Einfach den Heap
verkleinern reicht nicht, wie ich ausprobiert habe.
Hier das Kauderwelsch von LinkScript
olpo schrieb:> resource_NODE* resource;>> resource->next = &resource_list;
Autsch.
Nun hab dich nicht so. Willst du deinen Fehler finden oder nicht? SOllen
wir dir dabei helfen oder nicht?
Wenn du beide Fragen mit 'Ja' beantwortest, dann hör auf hier
Phantasiecode zu posten, der voller Fehler ist. Hier hat nämlich keiner
Lust, Phantomfehlern nachzulaufen.
Und wenn das da tatsächlich der Anfang der Funktion ist, dann wundert
mich nichts mehr. Schnelle Frage: Auf welches resource_NODE element
zeigt denn der Pointer resource, dessen next Feld du veränderst?
olpo schrieb:> resource_NODE* resource;
Hier hast du einen Zeiger, den du nicht initialisierst.
> resource->next = &resource_list;
Hier dereferenzierst du ihn. Du schreibst "in die Pampa".
olpo schrieb:> Hups...ist kein Fantasie-Code. Ich bin so.. :)>> So besser?
kommt drauf an wies weitergeht.
Was wird das hier: Programmieren per Ratespiel?
Karl Heinz Buchegger schrieb:> Was wird das hier: Programmieren per Ratespiel?
Sieht so aus ;)
Es gibt auch bei C manchmal ganz nette Seiteneffekte. Das sieht man
leider nur im Zusammenhang. Den Codeschnippseln nach frißt das eh
kein Compiler ...
Joachim Drechsel schrieb:> Karl Heinz Buchegger schrieb:>> Was wird das hier: Programmieren per Ratespiel?>> Sieht so aus ;)
Ich nehm den 50:50 Joker
> Es gibt auch bei C manchmal ganz nette Seiteneffekte. Das sieht man> leider nur im Zusammenhang. Den Codeschnippseln nach frißt das eh> kein Compiler ...
Den Codeschnipseln nach würd ich dem TO dringend ein paar
Trainingseinheiten zum Thema "dynamic data structures" auf dem PC
empfehlen. Mit besonderem Augenmerk auf penibler NULL-Initialisierung
ausnahmslos ALLER Pointer.
Jaja, amüsiert euch nur...
Wie ist das bei malloc()?
Das liefert ja auch nur einen Pointer zurück. Kann ich das dann gleich
nutzen, oder muss ich das zuerst auch mit "was konkreten" füllen?
Also,
olpo schrieb:> Jaja, amüsiert euch nur...
Wir amüsieren uns nicht.
Ganz im Gegenteil.
> Wie ist das bei malloc()?
Es liefert einen Pointer auf einen entsprechend großen Speicherbereich.
> Das liefert ja auch nur einen Pointer zurück. Kann ich das dann gleich> nutzen, oder muss ich das zuerst auch mit "was konkreten" füllen?
Da fehlts jetzt aber arg weit.
> Also,> [c]struct struktur{> int a;> int b;> };>> void bla(){>> struktur* s = malloc(sizeof(struktur));>> /* dann sollte ich das wohl nicht machen */>> s->a = 1234;
doch, das ist fein.
Du hast einen Pointer und der zeigt auf Speicher in dem ein struktur
Objekt existiert.
>> /* sondern zuerst initialisieren? */>> struktur init;
Und wie machst du die Initialisierung?
Richtig. Mit Zuweisungen. Womit wir wieder bei der Variante 1 wären.
> *s = init;
Das ist auch nichts anderes als eine Zuweisung. Nur dass du eine
komplette Struktur in einem Rutsch auf den Speicher kopierst wo der
Zeiger hinzeigt und in der Variante 1 kopierst du in Häppchen Member für
Member.
olpo schrieb:> Ich habe alle malloc()'s wieder ge-free()'d. Das sind auch nur kleine> malloc()'s von höchstens 20Byte
Ich kann mir nicht vorstellen, daß das mächtige malloc-Geschütz für nur
einige 20Byte überhaupt einen Sinn macht.
Warum kannst Du die Variablen nicht einfach schon zur Compilezeit
reservieren?
Nicht alle Techniken, die auf einem PC mit vielen GB RAM Sinn machen,
muß man auch einem MC aufzwingen.
20 Byte würde allerdings auch auf dem PC niemand mit malloc anlegen. Der
Verwaltungsaufwand wird schon ein Mehrfaches betragen. Häppchen unter
1kB lohnen sich dann nicht.
Peter