PIC18F2550 Loop Counter overwritten by sprintf

1

Tengo el siguiente código compilado con el compilador MPLab y XC8 de Microchip y ejecutándome 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 bucle for solo se repite una vez y durante esa iteración se ejecuta correctamente el segundo sprintf , pero después de ejecutarlo, el valor de i es algo aleatorio (26154, 8294, ...). He intentado cambiar i por otra variable j asignando el valor de i a j al comienzo del bucle, pero lo mismo sucede con i .

Parece que es algo con sprintf porque cuando uso el depurador, el valor de i no cambia hasta que se ejecuta sprint . Una cosa a tener en cuenta es que el valor en la salida es correcto (es decir, "el sensor 0 está actualmente desactivado \ r \ n") lo que hace que esto sea aún más desconcertante.

Este debe ser un código muy simple, pero no funciona y estoy seguro de que hay una explicación simple. ¿Dónde debería estar buscando?

    
pregunta Matt Ruwe

2 respuestas

9

Su problema es esta línea:

char output[20];

Estás asignando 20 caracteres al búfer para mantener tu cadena, y luego llamas a sprintf () para que la llene.

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 tendrá que 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á apagado \ r \ n

Hay 29 caracteres (suponiendo un número de dos dígitos). Esto da como resultado un desbordamiento del búfer, que comenzará a saturar 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:

  • todas las letras fijas de su mensaje.
  • el número más grande que la variable i mantendrá alguna vez.
  • el \r\n final.
  • el byte NUL de terminación.
respondido por el David
6

Su declaración char output es demasiado pequeña para la cadena en la que desea escribir.

Inténtalo de nuevo con char output[50]

Su variable de conteo 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 comprueba la longitud de la matriz en la que escribe. ¡Compruebe la longitud de la matriz antes de escribirla en el código!

    
respondido por el GER_Moki

Lea otras preguntas en las etiquetas