Guten Abend zusammen Ich habe einen Source Code, der in C wunderbar funktionierte und nun auch mit einem C++ Compiler funktionieren soll. So weit so gut... nun hab ich das Problem, dass bei folgender Zusweisung curr_frame->locals[i] = vm_args[i]; im Memory fälschlicherweise jeweils 1 Byte des vorherigen class_ptr mit 1 Byte Wert von vm_args überschrieben wird. vm_args ist natürlich ebenfalls vom Typ value_t. Woran könnte dies liegen? typedef PACKED struct frame_T frame_t; typedef PACKED union value_T value_t; struct frame_T { class_t *class_ptr; value_t locals[1]; }; union value_T { int32 i; float32 f; uint32 val; }; Die Struktur sowie die Union wurde mit #pragma pack(2) versehen, da diese typen mit dem alignment in einem file übereinstimmen müssen (und dies soweit auch tun). Ich benutze IAR als Compiler, die CPU ist ein LPC23xx von NXP. Ich hoffe, die Angaben reichen soweit mal... Danke für eure Hilfe. Gruss Fabian
ich weiß nicht wie du dir das denkst, aber bei curr_frame->locals[i] = vm_args[i]; darf i nur 0 annehmen, alles andere bringt nicht das gewünschte ergebnis.
1 | struct frame_T |
2 | {
|
3 | class_t *class_ptr; |
4 | value_t locals[1]; |
5 | ...
|
ein Array der Länge 1? Ich wittere da einen Array-Overflow.
Wozu ist hier die Packerei gut? Bei diesen Datentypen brennt auch ohne nichts an.
Karl Heinz Buchegger schrieb: > ein Array der Länge 1? Möglicherweise soll das ein "flexible array member" sein, wobei man diese seit C99 ohne Größenangabe schreibt, also
1 | struct frame_T |
2 | {
|
3 | class_t *class_ptr; |
4 | value_t locals[]; |
5 | };
|
Egal ob mit oder ohne Größenangabe, in C++ sind solche Dinge m.W. offiziell nicht vorgesehen (höchstens vielleicht in C++11), könnten aber trotzdem funktionieren. Ganz sicher kann man aber solche Strukturen nicht mit new anlegen, da man dort im Gegensatz zu malloc keine Größe übergibt, die ja in diesem Fall variabel ist. Vielleicht liegt also der Fehler darin, dass für die Strukturen zu wenig Speicher reserviert wird. Welche Absicht aber tatsächlich hinter der [1] steckt, das kann uns nur Fabian sagen.
Danke für eure Antworten. Warum die ganze packerei? Dies hat schon seinen Grund, denn der struct ist eigentlich deutlich grösser (dies ist nur das Ende davon...) und wird einerseits über bestehende Daten im Flash "gestülpt" und andererseits dient es zur Speicherung im RAM. Genau dort liegt das Problem. Genau so ist es, wir reden hier von einem "flexible Array Member". Aber warum wird dieses Array nicht richtig addressiert, auch wenn ich im Moment nur das Element 0 benutze? Muss zwingend malloc verwendet werden? Wurde im C Code übrigens auch nicht...
Fabian schrieb: > Die Struktur sowie die Union wurde mit #pragma pack(2) versehen, da > diese typen mit dem alignment in einem file übereinstimmen müssen Was soll das, mach ordentliche read und write Funktionen, dann muss gar nichts übereinstimmen und es ist portabel. Fabian schrieb: > und wird einerseits über bestehende Daten im Flash "gestülpt" Dasselbe wie oben, das ist Trickprogrammierung. Kann man machen wenn das genau für eine Anwendung und einen Prozessor gemacht wird, aber beim Portieren immer eine Lotterie. Wenn man hier nicht unbedingt das letzte halbe Prozent an Performance braucht, macht man sowas mit sauberen Konvertierfunktionen. Meine Meinung!
Fabian schrieb: > Warum die ganze packerei? Dies hat schon seinen Grund, denn der struct > ist eigentlich deutlich grösser (dies ist nur das Ende davon...) Ahnte ich es doch... Information hiding an entscheidender Stelle. Na dann such mal schön.
Naja, dann poste ich das nächste mal den ganzen Source Code... Gewisse Leute in diesem Forum werden, sofern sie nicht gerade eine Lösung bereit haben, seeehr schnell persönlich. Muss ich nicht haben! Auch meine Meinung!
Fabian schrieb: > Gewisse Leute in diesem Forum werden, sofern sie nicht gerade eine > Lösung bereit haben, seeehr schnell persönlich. ?? Falls mein Beitrag gemeint sein sollte, erklärs mir.
Fabian schrieb: > Naja, dann poste ich das nächste mal den ganzen Source Code... Die ganze Struktur wär schon mal ein Ansatz. Denn in der gezeigten Struktur ist kein Anlass für einen einzelnen Bytezugriff zu sehen. Aber generell gilt es, bei Suche nach hartnäckigen Fehlern das Programm auf das Minimum abzuspecken, in dem das Problem immer noch auftritt. Das hilft nicht nur beim Posten vom Code, sondern auch dir. Ausserdem solltest du deinen Code mal auf Stellen untersuchen, in denen die Adresse eines misaligned members verwendet wird, statt direkt darauf zuzugreifen. Ich weiss nicht wie IAR sich in diesem Fall verhält, aber bei GCC kann das grandios und ohne Warnung in die Hose gehen. > seeehr schnell persönlich Persönlich geht anders. Allerdings nervt es auf Dauer, wenn immer wieder Leute zielsicher genau jene Teile posten, die ziemlich wahrscheinlich nicht die Ursache des Problem sind (noch nerviger ist allerdings abgetippter Code der Marke "so ähnlich, nur ohne die ganzen Tipp- und Syntaxfehler").
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.