usar leaks como c linux valgrind

c - leaks - valgrind ubuntu



valgrind-Dirección-es de 0 bytes después de un bloque de tamaño 8 asignado (1)

strcpy agrega un carácter de terminador nulo ''/0'' . Olvidaste asignar espacio para ello:

*filename = (char*)realloc(*filename, strlen(*collection_name)*sizeof(char)+5);

".tde" agregar espacio para 5 caracteres: 4 para el sufijo ".tde" y uno más para el terminador ''/0'' . Su código actual asigna solo 4, por lo que la última escritura se realiza en el espacio inmediatamente después del bloque que ha asignado para el nuevo nombre de archivo (es decir, 0 bytes después de él).

Nota: Su código tiene un problema común: asigna los resultados de la realloc directamente a un puntero que se está reasignando. Esto está bien cuando realloc es exitoso, pero crea una pérdida de memoria cuando falla. Arreglar este error requiere almacenar el resultado de la realloc en una variable separada, y verificar que no haya NULL antes de volver a asignar el valor a *filename :

char *tmp = (char*)realloc(*filename, strlen(*collection_name)*sizeof(char)+5); if (tmp != NULL) { *filename = tmp; } else { // Do something about the failed allocation }

Asignar directamente a *filename crea una pérdida de memoria, ya que el puntero al que *filename ha estado apuntando a continuación se sobrescribiría en caso de error, y no se podría recuperar.

En primer lugar, sé que se han formulado preguntas similares . Sin embargo, me gustaría tener una pregunta simple más general con tipos de datos C realmente primitivos. Asi que aqui esta.

En main.c llamo a una función para rellenar esas cadenas:

int main (int argc, char *argv[]){ char *host = NULL ; char *database ; char *collection_name; char *filename = ""; char *fields = NULL; char *query = NULL; ... get_options(argc, argv, &host, &database, &collection_name, &filename, &fields, &query, &aggregation);

Dentro de get_options :

if (*filename == NULL ) { *filename = (char*)realloc(*filename, strlen(*collection_name)*sizeof(char)+4); strcpy(*filename, *collection_name); strcat(*filename, ".tde"); # line 69 }

Mi programa funciona bien, pero Valgrind me dice que lo estoy haciendo mal:

==8608== Memcheck, a memory error detector ==8608== Copyright (C) 2002-2011, and GNU GPL''d, by Julian Seward et al. ==8608== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info ==8608== Command: ./coll2tde -h localhost -d test -c test ==8608== ==8608== Invalid write of size 1 ==8608== at 0x403BE2: get_options (coll2tde.c:69) ==8608== by 0x402213: main (coll2tde.c:92) ==8608== Address 0xa2edd18 is 0 bytes after a block of size 8 alloc''d ==8608== at 0x4C28BED: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==8608== by 0x4C28D6F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==8608== by 0x403BBC: get_options (coll2tde.c:67) ==8608== by 0x402213: main (coll2tde.c:92)

¿Puede explicar el error? La Address 0xa2edd18 is 0 bytes after a block of size 8 alloc''d ? ¿Cómo puedo resolver este problema?