Ich habe den folgenden Code mit dem MPLab- und XC8-Compiler von Microchip kompiliert und auf einem PIC18F2550 ausgeführt, der etwas ziemlich Seltsames macht:
char output[20];
int i = 0;
char currentStatus = readShiftReg();
for (i = 0; i < 8; i++) {
if ((currentStatus & (1 << i)) == (1 << i))
sprintf(output, "Sensor %d is currently on \r\n", i + 1);
else
sprintf(output, "Sensor %d is currently off \r\n", i + 1);
putsUSART(output);
}
Die for-Schleife wird immer nur einmal durchlaufen und während dieser einen Iteration wird die zweite korrekt ausgeführt sprintf
, aber nachdem sie ausgeführt wurde, i
ist der Wert von zufällig (26154, 8294, ...). Ich habe versucht, am Anfang der Schleife i
gegen eine andere Variable auszutauschen, die den Wert von j
zuweist , aber das Gleiche passiert immer noch mit .i
j
i
Es scheint, als wäre es etwas mit sprintf
, denn wenn ich den Debugger verwende, i
wird der Wert von erst nach den Läufen geändert sprint
. Eine Sache, die zu beachten ist, ist, dass der Wert in der Ausgabe korrekt ist (dh "Sensor 0 ist derzeit aus \r\n"), was dies noch verwirrender macht.
Dies sollte ein sehr einfacher Code sein, aber er funktioniert nicht und ich bin sicher, dass es eine einfache Erklärung gibt. Wo soll ich suchen?
Dein Problem ist diese Zeile:
char output[20];
Sie weisen dem Puffer 20 Zeichen für Ihre Zeichenfolge zu und rufen dann sprintf() auf, um ihn zu füllen.
Ihre Formatzeichenfolge ist jedoch zu lang, noch bevor der Dezimalwert enthalten ist. Denken Sie daran, dass das letzte Array-Element immer (ein NUL-Zeichen) sein muss, \x00
Sie haben 19 Zeichen für Ihre Nachricht.
Zählen Sie die Anzahl der Zeichen in dieser Zeichenfolge:
Sensor %d ist derzeit ausgeschaltet \r\n
Es gibt 29 Zeichen (unter der Annahme einer zweistelligen Zahl). Dies führt zu einem Pufferüberlauf, der andere Variablen überlastet und dazu führen kann, dass Ihr Programm auf unerwartete Weise arbeitet. Es ist eine häufige Art von Sicherheitsproblem in C.
Erhöhen Sie die Größe Ihres Puffers, sodass er groß genug ist, um Folgendes aufzunehmen:
i
jemals enthalten wird.\r\n
.Ihre char output
Deklaration ist zu klein für die Zeichenfolge, in die Sie schreiben möchten.
Probier es nochmal mitchar output[50]
Ihre Zählvariable i
wird direkt hinter der letzten Variablen des Char-Arrays gespeichert.
Etwas wie das:
Adress Value
0x0F00 char[0]
0x0F01 char[1]
. .
. .
. .
0x0F19 char[19] <-- last variable of char
0x0F20 i <-- counter variable
Jetzt überprüft sprintf nicht die Länge des Arrays, in das es schreibt. Überprüfen Sie die Länge des Arrays, bevor Sie es in Code schreiben!
Matt Ruwe
Majenko