Обнаружено разрушение стека. C программирование

Я пытаюсь запустить программу на Си. Вроде хорошо работает, но в конце показывает:

ОБНАРУЖЕНО СТЕЙК

Это код:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

extern int errno;

int main(int argc, char *argv[]){  /*Para pasar argumentos a la funcion main*/

char id[7]="\0";       
char orden[10]="\0";   
char arg[3]="\0";
char idhijo[7]="\0";      
char ordenhijo[10]="\0";   
char arghijo[3]="\0";

int i=0, j=0, k=0;

int a=1, pipe1[2], pipe2[2], control, argument=0, status, posx=50, posy=50, s, t, arg_val=0, orden_val=0;

FILE *fichero;

char mensaje1[4], mensaje2[4], mensaje3[6];
char posxpadre[4]="50", posypadre[4]="50", hijoPID[4];

system("clear");

control = pipe(pipe1);
if(control !=0){

perror("pipe1");
exit(errno);
}

control = pipe(pipe2);
if(control !=0){

perror("pipe2");
exit(errno);
}

control = fork();                            

fichero=fopen(argv[1], "r");
if (fichero){

while((i != EOF) && (j != EOF) && (k != EOF)){


if((i != EOF) && (j != EOF)  && (k != EOF)){

     if (control ==-1){

     perror("fork");
     exit(errno);

  }


  if (control !=0){


        k=fscanf(fichero, "%s", id);
        i=fscanf(fichero, "%s", orden);
        j=fscanf(fichero, "%s", arg);


        if(Robot_valido(id)){  

            write(pipe1[1], id, 7);
                write(pipe1[1], arg, 3);
                write(pipe1[1], posxpadre, 4);            
                write(pipe1[1], posypadre, 4);
                write(pipe1[1], orden, 10);

            read(pipe2[0], posxpadre, 4);
            read(pipe2[0], hijoPID, 6);
            read(pipe2[0], posypadre, 4);            

            printf("Hijo con PID %s desplazo el robot a la posicion: (%s, %s)\n\n", hijoPID, posxpadre, posypadre);

            }
 }

else{

    read(pipe1[0], idhijo, 7);
    read(pipe1[0], arghijo, 3);
    read(pipe1[0], posxpadre, 4);
    read(pipe1[0], posypadre, 4);
    read(pipe1[0], ordenhijo, 10);

    if (Robot_valido(idhijo)!=0){

        Orden_valida(ordenhijo, arghijo, &orden_val, &arg_val);

        if (orden_val !=0 && arg_val !=0){

            argument=atoi(arghijo);
            posy=atoi(posypadre);
            posx=atoi(posxpadre);

        if (strcmp(ordenhijo, "arriba")==0){

             if (posy>1){

               while (argument > 0){

                   if (posy>0){

                   posy--;
                   argument--;
                       }

                   else{

                   argument=0;
                   }
               }
                   }
             }

         if (strcmp(ordenhijo, "abajo")==0){

                   if (posy<100){

               while (argument > 0){

                    if (posy<100){
                    posy++;
                    argument--;

                     }

                     else{

                     argument=0;
                     }
                 }
                    }
             }

         if (strcmp(ordenhijo, "derecha")==0){

                    if (posx<100){

                  while (argument > 0){

                   if (posx<100){
                       posx++;
                       argument--;

                       }

                   else{
                        argument=0;
                   }
                 }
                }
             }

         if (strcmp(ordenhijo, "izquierda")==0){

                 if (posx>0){

                  while (argument > 0){

                    if (posx>0){
                       posx--;
                       argument--;
                        }

                    else{

                       argument=0;
                    }
                      }
                 }
             }



         printf("Robot desplazado hasta la posicion: (%d, %d)\n", posx, posy);



         sprintf(mensaje1, "%d", posx);   
         sprintf(mensaje2, "%d", posy);
         sprintf(mensaje3, "%d", getpid());      

         write(pipe2[1], mensaje1, 4);
             write(pipe2[1], mensaje3, 6);
         write(pipe2[1], mensaje2, 4);

         }

    }

    }
  } 
}

 close(pipe1[0]);
 close(pipe1[1]);
 close(pipe2[0]);
 close(pipe2[1]);

 }

 }

Кто-нибудь знает, почему это происходит? Я провел много исследований в Google, но все возможные ответы не помогли. Любая помощь будет очень полезна.

Спасибо вам всем!!

1 ответ

Вы делаете много ввода-вывода в очень маленькие буферы. Если какой-либо из этих переполнений, они очень вероятно разбьют стек.

Вы должны запустить вашу программу в Valgrind, если это возможно. Вы также можете попробовать увеличить размеры буферов и переключиться с fscanf() что-то более безопасное (например, чтение одной полной строки с fgets() а затем разбирать его в памяти).

 read(pipe2[0], hijoPID, 6);

должно быть

 read(pipe2[0], hijoPID, 4);

Это не единственная проблема, хотя. Вы должны использовать константы для вашей ширины, чтобы этого не произошло.

const int hijoPID_l = 4;
read(pipe2[0], hijoPID, hijoPID_l);

Также, когда вы делаете fscanf, вы должны указать свою ширину.

k=fscanf(fichero, "%7", id);
i=fscanf(fichero, "%10", orden);
j=fscanf(fichero, "%3", arg);

Если вы используете константы для ваших длин, то, например,

char fmt_id[8];
sprintf(fmt_id, "%%%d", id_l);
k=fscanf(fichero, fmt_id, id);

может использоваться для динамического создания строк формата в начале цикла, а затем повторно использоваться для каждого fscanf(),

Другие вопросы по тегам