简体   繁体   English

检测到C堆粉碎

[英]C stack smashing detected

I have a function that counts how many times a words appears on a file. 我有一个函数可以计算单词出现在文件上的次数。 Now for some reason it gets stack smashing detected error, and i dont see the error. 现在由于某种原因它得到堆栈粉碎检测到的错误,我没有看到错误。

Here is the code: 这是代码:

int contar_palabra(const char *nombre_file, const char *palabra){

/*variables locales*/
FILE *file; 
char buffer[50]; 
int bytes_leidos, contador = 0, comparar, cerrar, i;    

/*Abrimos el archivo para lectura*/
file = fopen(nombre_file, "r");

/*Verificamos que se haya abierto correctamente*/
if (file == NULL){
  printf("No se pudo abrir el archivo \n");
  perror(nombre_file);
  exit(EXIT_FAILURE);
}

/*Procedemos a contar cuantas veces aparece una palabra*/
while (!feof(file)){

  bytes_leidos = fscanf(file, "%s", buffer);

  if (bytes_leidos > 0){

    /*Hacemos la comparacion*/
    comparar = strcmp(buffer, palabra);
    if (comparar == 0)
      contador++;
  }
  else if(errno == EOF)     
        printf("Error al leer alguna palabra de %s \n", nombre_file);
  else if (bytes_leidos == EOF)
    break;
}

cerrar = fclose(file);

if(cerrar == EOF){
  printf("Error: no se pudo cerra el archivo.");
}

printf("antes de retornar contador \n");
return contador; 

} }

I used valgrind trying to identify the error, and the log file gave me this: 我用valgrind试图识别错误,日志文件给了我这个:

  ==2252== Memcheck, a memory error detector
  ==2252== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
  ==2252== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
  ==2252== Command: ./pargrep viejo.txt
  ==2252== Parent PID: 1756
  ==2252== 
  ==2252== 
  ==2252== HEAP SUMMARY:
  ==2252==     in use at exit: 55 bytes in 1 blocks
  ==2252==   total heap usage: 7 allocs, 6 frees, 1,389 bytes allocated
  ==2252== 
  ==2252== 55 bytes in 1 blocks are still reachable in loss record 1 of 1
  ==2252==    at 0x4026864: malloc (vg_replace_malloc.c:236)
  ==2252==    by 0x40B878B: __libc_message (libc_fatal.c:138)
  ==2252==    by 0x413D09F: __fortify_fail (fortify_fail.c:32)
  ==2252==    by 0x413D049: __stack_chk_fail (stack_chk_fail.c:29)
  ==2252==    by 0x8049142: contar_palabra (in /home/alessandro/OS/Proyecto2/prueba1.0/pargrep)
  ==2252==    by 0x80489D4: main (in /home/alessandro/OS/Proyecto2/prueba1.0/pargrep)
  ==2252== 
  ==2252== LEAK SUMMARY:
  ==2252==    definitely lost: 0 bytes in 0 blocks
  ==2252==    indirectly lost: 0 bytes in 0 blocks
  ==2252==      possibly lost: 0 bytes in 0 blocks
  ==2252==    still reachable: 55 bytes in 1 blocks
  ==2252==         suppressed: 0 bytes in 0 blocks
  ==2252== 
  ==2252== For counts of detected and suppressed errors, rerun with: -v
  ==2252== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 8)

Whats strange is that it prints a message before returning. 奇怪的是它在返回之前打印了一条消息。 I really dont see the error, appreciate the help. 我真的没有看到错误,感谢帮助。 thanks in advance 提前致谢

Using plain %s as a format specifier to fscanf is very dangerous as you have no protection against writing beyond the end of the buffer which is only 50 bytes in your case. 使用普通的%s作为fscanf的格式说明符是非常危险的,因为你没有防止写入超出缓冲区末尾的保护,在你的情况下只有50个字节。 Consider providing a width modifier to the format specifier, although this will be handling an accurate count when the width limit is reached more complex. 考虑为格式说明符提供宽度修饰符,但是当宽度限制达到更复杂时,这将处理准确的计数。

You may find that reading character by character ( fgetc ) or reading fixed buffers ( fread ) and detecting the word separators by hand yields simpler code. 您可能会发现逐字符读取( fgetc )或读取固定缓冲区( fread )并手动检测单词分隔符会产生更简单的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM