2 votes

Strlen Valgrind lecture invalide de la taille 1

Dans ce programme, j'essaie de prendre les informations stockées dans un fichier, puis de les rechercher pour trouver le numéro stocké. J'ai supprimé la partie où j'itère dans le fichier pour trouver le nombre stocké, car cette partie fonctionne bien. Cependant, dans cette section, il y a une erreur à la ligne 63 (celle avec le symbole strlen ) qui provoque une erreur valgrind pour signaler

==4149== Memcheck, a memory error detector
==4149== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==4149== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==4149== Command: main.o
==4149== 
==4149== Invalid read of size 1
==4149==    at 0x4C2EDB4: strlen (vg_replace_strmem.c:454)
==4149==    by 0x108B9E: main (main.c:63)
==4149==  Address 0x54de5f7 is 0 bytes after a block of size 23 alloc'd
==4149==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==4149==    by 0x108B62: main (main.c:56)
==4149== 

Voici le code :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

int findSize(char file_name[]) { 
    // opening the file in read mode 
    FILE *fp = fopen(file_name, "r"); 

    // checking if the file exist or not 
    if (fp == NULL) { 
        printf("File Not Found!\n"); 
        return -1; 
    } 

    fseek(fp, 0L, SEEK_END); 

    // calculating the size of the file 
    int res = ftell(fp); 

    // closing the file 
    fclose(fp); 

    return res; 
} 

int main() {
    char *buffer = 0;   //contents of the file
    long int is = 0; // thing that will be returned
    long int ie = 0;    // thing that will be returned
    int index1; //index of "s"
    int index2; //index of "e"
    char *a;    //phrase after s
    char *b;    //phrase after e
    int bufferlength;   //length of txt file
    int negativeCount1 = 0;
    int negativeCount2 = 0;
    long length;
    char file_name[] = { "filename" }; 
    FILE *f = fopen(file_name, "rb");

    int res = findSize(file_name); 
    if (res != -1) 
        printf("Size of the file is %d bytes \n", res); 
    if (res == 0) {
        printf("empty file detected");
        return 0;
    }

    if (f) {
        {
            fseek(f, 0, SEEK_END);
            length = ftell(f);
            fseek(f, 0, SEEK_SET);
            buffer = malloc(length);
            if (buffer) {
               fread(buffer, 1, length, f);
            }
            fclose(f);
        }
        bufferlength = strlen(buffer);
        printf("%d \n", bufferlength);
    }
}

2voto

Kamil Cuk Points 11578

En C, les cordes sont zéro terminé - le dernier élément d'une chaîne doit être égal à zéro. Dans le cas où tous les length les caractères que vous lisez dans le fichier sont différents de zéro, strlen() lira au-delà de la fin du tampon lors de la recherche de l'octet zéro.

Si vous l'avez, vous pouvez utiliser strnlen() pour limiter la longueur maximale du tampon strlen() va essayer de mesurer :

 bufferlength = strnlen(buffer, length);
 // you can also limit printf
 printf(".*s\n", (int)length, buffer); // pendantics would check if length <= INT_MAX

Ou, typiquement, allouer un octet de plus et s'assurer que le dernier octet est zéro, de sorte que strlen() ne lit pas derrière buffer .

  buffer = malloc(length + 1); // allocate one more
  // your error handling of failed allocation is strange
  if (buffer != NULL) { 
      abort();
  }
  buffer[length] = '\0'; // null terminate buffer
  fread (buffer, 1, length, f);
  fclose (f);
  bufferlength = strlen(buffer); // will read at max `length + 1` characters, 
                                 // because `buffer[length] = '\0'`
  printf("%s\n", buffer); // buffer is zero terminated - valid

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X