sprintf überschreibt RAM-Bereich

Gast #502431
Lesenswert?

Hallo allerseits!

Ich komm einem Fehler nicht auf die Spur.
Habe einen Puffer deklariert mit 12 Bytes.
Im Programm schreibe ich dann mit der sprintf -Funktion einen
Longwert in diesen Puffer (belegt nur 10Bytes).
Nun passiert es; nach ausführen des sprinf ändern sich Variablen mitten 
im Speicherbereich des RAM.
Warum macht er das denn nur???

Prinzip:

long Wert;     (alles unsigned)
char puffer[12];
char Variable2;
char Variable3;
.
.
char Variable20;
char Variable21;
char Variable22;
.
.
void main (void){
.
alle Variablen auf 0;
.
  for(;;){
  .
  .
  (Variable21 und Variable22 noch OK)
  sprintf(puffer,"=L%06lu\n\r",Wert);
  (hier sind die beiden Variablen mit anderen Werten überschrieben)
  .
  .
  }
}

Ich Benutze deb MSP430F1232.
Programm hat bisher einwandfrei Funktioniert. Erst seit dem ich die
Variablen21 und 22 hinzugefügt habe tritt dieser Fehler auf.
Der Compiler sagt, dass erst 141 Byte des RAM belegt sind.
Der MSP hat 256Byte RAM.

Vielleicht hat jemand 'ne Idee.

Schönen Tag noch!

Gruß Rainer
Gast #502448
Lesenswert?

Hallo ARM-Fan!

Glaube nicht!
Das dachte ich zuerst auch. Hab dann vor dem Programmstart den 
kompletten RAM     auf 0 gesetzt. Nach dem Fehler sind die Bytes 
zwischen diesen Variablen und dem Stack unverändert auf 0.
Gut nicht wirklich alle. Von der Variablen-Seite her ändern sich noch 
5-6 Bytes. Das Verstehe ich auch schon nicht. Dachte mir einfach, den 
Platz nimmt der Compiler irgenwie her, da dort keine Variablen 
angesiedelt sind.
Aber die beiden oben genannten Variablen sind ja deklariert, und können 
doch eigentlich nicht wegoptimiert werden.

ODER?

Trotzdem Danke für die schnelle Antwort, das ging ja flott!!

Rainer
Gast #503739
Lesenswert?

Die sprintf soll ja ziemlich speicherhungrig sein.
Sollte man auf diese Funktion auf relativ kleinen µC besser verzichten?
Wie gesagt, mein µC hat 256 Bytes. Davon sind laut Compiler 141 belegt.
Da sollte aber doch eigentlich noch Platz vorhanen sein? ODER?
#503781
Lesenswert?

> sprintf erwartet nicht die Variable selbst, sondern einen Zeiger auf die
> Variable.

Nein

> int sprintf(char *buffer, const char *format[, argument, ...]);

Da steht:
1. Argument Zeiger auf einen Buffer in den der String geschrieben werden 
soll
=> puffer

2. Zeiger auf einen String der beschreibt wie der String aussehen soll
=> ,"=L%06lu\n\r",

3. optional weitere Parameter
In diesem Fall Wert.

Genau wie bei printf. Das sieht im Code gut aus.

Wie groß ist eigentlich Wert in diesem Beispiel? Wenn die Zahl mehr als 
6 Dezimalstellen groß ist, langen die 12 Byte für puffer nicht und die 
nachfolgenden Speicherstellen werden überschrieben.
#503782
Lesenswert?

Die häufigste Ursache für solches Verhalten ist es,
wenn der aufnehmende String-Buffer zu klein dimensioniert
ist.

Daher die Frage: Da oben, ist das realer Code oder
ist das ein Beispiel, welches für das Forum konstruiert
wurde?

Zähl mal den Formatstring ab, wieviele Zeichen da
tatsächlich generiert werden. Berücksichtige auch,
dass Formatangaben wie %06lu durchaus auch mehr als
6 Zeichen liefern können (wenn die Zahl mit 6 Ziffern
nicht darstellbar ist, wird das Feld eigenmächtig vergrößert).
Gast #503786
Lesenswert?

OK.
Aber darauf habe ich doch keinen Einfluss. Oder?

Mit
sprintf(puffer,"=L%06lu\n\r",Wert);
gebe ich doch eigentlich den Wert an;
Verstehe ich da was falsch? Wie soll ich das anderst machen, als die 
Variable zu definieren, und sie dann der sprinf zu übergeben.

Oder muss ich da erst einen Zeiger anlegen, und diesen auf den Wert 
zeigen lassen?
Gast #503791
Lesenswert?

und dann gibts da noch die Probleme mit long-Werten, standardmässig 
arbeiten viele Compiler für MCs erstmal nur mit int, um (s)printf() 
grössenmässig nicht zu sehr aufzublähen. Um welchen Compiler gehts 
überhaupt? Compileroptions?
Gast #503812
Lesenswert?

Habs jetzt mal mit einer Puffergröße von 20 Byte probiert 
(sicherheitshalber), und den Puffer ans Ende der Variablendeklaration 
gelegt.

Genau der gleiche Fehler.
Immer verschreibt die sprintf den RAM-Speicher ab der Adresse 0x23C.
Diesmal eben den Puffer ab Puffer[16].
Gast #503826
Lesenswert?

Setz doch mal die Deklaration "char puffer[12];" ans Ende der 
Variablendeklarationen. Nicht dass ich wüßte, was das für Auswirkungen 
haben wird, aber vielleicht bringt es irgenwelche neuen Einsichten 
(alles funktioniert: nicht so gut, weil Ursache immer noch unklar / 
Absturz: Code hinter puffer wurde tatsächlich überschrieben).
Gast #503836
Lesenswert?

Hab ich schon.

Siehe ein Beitrag zuvor, mit "char puffer[20];"
Es überschreibt mir die letzten stellen vom Puffer
(Puffer[16],Puffer[17],Puffer[18],Puffer[19]).
Wieder ab der Adresse 0x23C; wie zuvor.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren