Komisches verhalten beim lesen von Array

OP #6372478
Lesenswert?

Hallo,
Ich arbeite an einem kleinen Projekt, in dem ich mit einem Attiny817 
eine 25 Byte lange UART-Nachricht lese und diese anschließend mit 
Bit-Verschiebungen weiterverarbeite (es handelt sich um ein SBUS Signal 
eines RC Empfängers).
Wenn ich jedoch mein rec[] Array auslese, verändert dieses sich ganz 
komisch.
Mein Array ist so definiert:
1
volatile uint8_t rec[48]; //(habs auch schon als uint16_t probiert)
(es ist extra groß, um einen Überlauf bei verpassen des Nachricht-endes 
zu vermeiden)
Zum testen habe ich nach dem vollständigen Empfang jede Stelle des 
Arrays auf 1 gesetzt und die stelle 0 ausgegeben. Vor dem erneuten auf 1 
schreiben habe ich die stelle 0 auch ausgegeben um zu sehen, was für ein 
Wert sie hatte.
1
 
2
char strr[20];
3
sprintf(strr,"=%d \r\n", (int)rec[0]);
4
printString(strr);
5
for (int i = 0; i < 25; i++)
6
{
7
      rec[i] = 1;
8
}
9
char strrr[20];
10
sprintf(strrr,"-%d \r\n", (int)rec[0]);
11
printString(strrr);
Aus dem zweiten print kommt wie zu erwarten "1", aus dem ersten kommt 
jedoch abhängig von meinem restlichen Programm was ganz anders raus, 
obwohl ich nie in das Array schreibe. Ich habe zuerst besagte 
Weiterverarbeitung auskommentiert und aus beiden prints eine "1" 
bekommen. Wenn ich nun aber eine beliebige Zeile einkommentiere, selbst 
wenn diese überhaupt nichts mit der stelle 0 zu tun hat, wird diese 
trotzdem verändert.
Mit
1
channels[15] = (uint16_t) ((rec[21]>>5|rec[22]>>3) & 0x07FF);
kommt aus dem ersten print eine "0" raus.
Mit
1
channels[15] = (uint16_t) ((rec[21]>>5|rec[22]) & 0x07FF);
oder
1
channels[15] = (uint16_t) ((rec[21]|rec[22]>>3) & 0x07FF);
kommt aus dem ersten print eine "1" raus, obwohl ich an der 0. stelle 
gar nichts verändere.
Teilweise ist auch, mit klammern um den Verschiebungen, eine "8" oder 
"9" gekommen. Ich habe es auch schon mit mehr als nur dem einen 
(uint16_t) cast probiert, da es ja scheinbar etwas damit zu tun haben 
muss, aber funktioniert hat es danach auch nicht. Hat hier vielleicht 
jemand eine Idee, warum sich das Array so komisch verhält, bzw. warum 
ich eine stelle am fast anderen ende des Arrays beeinflusse?
Danke und Gruß,
Nils
Gast #6372495
Lesenswert?

Nils K. schrieb:
> (es ist extra groß, um einen Überlauf bei verpassen des Nachricht-endes
> zu vermeiden)
Das kann doch wohl kein Argument für die Array-Größe sein. Was passiert, 
wenn du das Ende zwei mal verpasst?
Reduzierte Fehler-/Absturzwahrscheinlichkeit?

> Hat hier vielleicht jemand eine Idee, warum sich das Array so komisch
> verhält, bzw. warum ich eine stelle am fast anderen ende des Arrays
> beeinflusse?

Was liegt denn vor dem Array im Speicher?

Guck dem Array und deinen Variable, notfalls auch den Registern im 
Simulator oder besser im Debugger auf die Finger.
#6372501
Lesenswert?

Nils K. schrieb:
> char strr[20];
> sprintf(strr,"=%d \r\n", (int)rec[0]);
> printString(strr);
> for (int i = 0; i < 25; i++)
> {
>       rec[i] = 1;
> }
> char strrr[20];
> sprintf(strrr,"-%d \r\n", (int)rec[0]);
> printString(strrr);
>
> Aus dem zweiten print kommt wie zu erwarten "1", aus dem ersten kommt
> jedoch abhängig von meinem restlichen Programm was ganz anders raus,
> obwohl ich nie in das Array schreibe.

Nunja, wenn du die strr[20] erzeugst (1 Zeile), dann ist der Inhalt 
undefiniert - deshalb kommt bei der ersten Ausgabe einfach irgendwas, 
das was grad im RAM an der Stelle liegt.
Gast #6372506
Lesenswert?

Adam P. schrieb:
> Nunja, wenn du die strr[20] erzeugst (1 Zeile), dann ist der Inhalt
> undefiniert - deshalb kommt bei der ersten Ausgabe einfach irgendwas,
> das was grad im RAM an der Stelle liegt.

Sicher?

"All array elements that are not initialized explicitly are 
zero-initialized."
https://en.cppreference.com/w/c/language/array_initialization
https://www.cs.uic.edu/~jbell/CourseNotes/C_Programming/Arrays.html
OP #6372769
Lesenswert?

Das str[20] ist nur für meine print Ausgabe und deswegen einfach groß um 
den Überlauf bei 32bit zahlen zu vermeiden (aus anderem Projekt 
kopiert). In sprintf habe ich ein "-" und ein "=" voresetzt, um die 
beiden nicht zu verwechseln, heißt bei dem oberen print block erhalte 
ich "=(zahl)" und bei dem unteren "-(zahl)".

Das Array "channels" war als "volatile uint16_t channels[15];" 
definiert, was heißt, dass es die stelle 15 gar nicht gab. Wie immer ist 
es solch eine Kleinigkeit, die das ganze kaputt macht. Es ist jetzt als 
"channels[16]" definiert und funktioniert.
Danke für die Antworten und Tipps, soweit hatte ich gar nicht gedacht.

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