Tengo el siguiente código compilado con el compilador MPLab y XC8 de Microchip y ejecutándose en un PIC18F2550 que está haciendo algo bastante extraño:
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);
}
El ciclo for solo itera una vez y durante esa iteración ejecuta correctamente el segundo sprintf
, pero después de ejecutarlo, el valor de i
es algo aleatorio (26154, 8294, ...). Intenté cambiar i
por otra variable j
asignando el valor de i
to j
al comienzo del ciclo, pero todavía sucede lo mismo con i
.
Parece que es algo sprintf
porque cuando uso el depurador, el valor de i
no cambia hasta después de sprint
las ejecuciones. Una cosa a tener en cuenta es que el valor en la salida es correcto (es decir, "El sensor 0 está actualmente apagado \r\n") lo que hace que esto sea aún más desconcertante.
Esto debería ser una pieza de código muy simple, pero no funciona y estoy seguro de que hay una explicación simple. ¿Dónde debería estar buscando?
Tu problema es esta línea:
char output[20];
Está asignando 20 caracteres para que el búfer contenga su cadena, luego llama a sprintf() para llenarlo.
Sin embargo, su cadena de formato es demasiado larga, incluso antes de que se incluya el valor decimal. Recordando que el último elemento de la matriz siempre deberá ser \x00
(un carácter NUL), tiene 19 caracteres para usar en su mensaje.
Cuente el número de caracteres en esta cadena:
El sensor %d está actualmente apagado \r\n
Hay 29 caracteres (asumiendo un número de dos dígitos). Esto da como resultado un desbordamiento del búfer, que comenzará a aplastar otras variables y puede hacer que su programa funcione de manera inesperada. Es un tipo común de problema de seguridad en C.
Aumente el tamaño de su búfer para que sea lo suficientemente grande como para contener:
i
jamás tendrá.\r\n
.Su char output
declaración es demasiado pequeña para la cadena que desea escribir.
Inténtalo de nuevo conchar output[50]
Su variable de recuento i
se guarda directamente detrás de la última variable de la matriz de caracteres.
Algo como esto:
Adress Value
0x0F00 char[0]
0x0F01 char[1]
. .
. .
. .
0x0F19 char[19] <-- last variable of char
0x0F20 i <-- counter variable
Ahora sprintf no verifica la longitud de la matriz en la que escribe. ¡Compruebe la longitud de la matriz antes de escribirla en el código!
matt ruwe
Majenko