Lectura no válida del tamaño 1 en strstr() usando valgrind
Frecuentes
Visto 3,883 veces
2
Estoy inspeccionando un fragmento de código con valgrind y me sale este error:
==7001== Invalid read of size 1
==7001== at 0x402E21B: strstr (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==7001== by 0x8049742: replace_in_file (functions.c:191)
==7001== by 0x8049C55: parse_dir (functions.c:295)
==7001== by 0x8049059: main (main.c:214)
==7001== Address 0x42018c3 is 0 bytes after a block of size 3 alloc'd
==7001== at 0x402B018: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==7001== by 0x80496EC: replace_in_file (functions.c:183)
==7001== by 0x8049C55: parse_dir (functions.c:295)
==7001== by 0x8049059: main (main.c:214)
El fragmento de código tiene el siguiente aspecto:
long int replace_in_file(char **sets, FILE *file, char *path, const char *mode){
long int n = 0, size = 0, len, remaining_len;
char *buffer,
*found,
*before,
*after;
size = file_size(file);
if(-1 != size){
buffer = malloc(size * sizeof(char));
rewind(file);
fread(buffer, 1, size, file);
int i=0;
do{
do{
found = strstr(buffer, sets[i]); // LINE 191
if(NULL != found && '\0' != sets[i][0]){
//rest of code...
No puedo darme cuenta por qué recibo ese error, porque todo funciona como se esperaba y en el depurador todas las variables parecen estar bien.
¿Qué está mal, cómo puedo solucionarlo?
3 Respuestas
5
fread()
sí no anular los datos que lee, pero strstr()
espera una cadena terminada en NUL. Debe asignar tamaño + 1 bytes y agregar explícitamente el terminador nul para estar seguro.
contestado el 03 de mayo de 12 a las 17:05
4
Tus buffer
no tiene terminación nula. Por lo general, solo puede bzero()
antes de la fread()
para asegurarse de que funcionará con strstr()
y funciones similares.
contestado el 03 de mayo de 12 a las 17:05
2
de lo que leí en mi página de manual, fread()
no NULL
-terminar su resultado de acuerdo con C89 - y tampoco en mi sistema - así que strstr()
simplemente leerá el final de buffer
a menos que lo termine, por ejemplo, así
buffer = malloc((size + 1) * sizeof(char));
memset(buffer, '\0', size + 1);
(que tiene la ventaja de terminarlo también en caso de que fread no pueda leer todo el archivo)
una nota al margen: dado que ya usas sizeof(char)
en tu malloc()
llamada, también podría considerar reemplazar el 1
en la fread()
en aras de la consistencia.
contestado el 03 de mayo de 12 a las 18:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas c valgrind strstr or haz tu propia pregunta.
¿Puedes garantizar que
buffer
es Nul-terminado después de lafread()
? noto que nobzero()
eso o cualquier cosa. - chrisaycock¿Cuántos punteros (char *) hay en la matriz (conjuntos)? ¿Es posible que sets[i] tenga un valor para i que lo coloque fuera de la matriz (sets)? Además, ¿cómo se garantiza que (el búfer) terminará en NUL? fread() no hará eso por ti... - Jeremy Friesner
¿Hay alguna posibilidad de que file_size devuelva 0? Yo usaría if(size > 0) en tu condicional. - Burton Samograd
Resuelto, @chrisaycock, agrega tu respuesta para que pueda aceptarla, ese era el problema. Jeremy Friesner, vi tu respuesta después de resolverlo. - Paul
Bien, lo publiqué como respuesta. También deberías votar Error fatal ya que encontró el mismo error. - chrisaycock