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.
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
structframe_T
2
{
3
class_t*class_ptr;
4
value_tlocals[];
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").