2016-07-24 1 views
-2

La fonction load ci-dessous tente de charger le contenu du fichier pointé par le file et enregistrer son emplacement à content et la longueur length. Le code fonctionne bien mais Valgrind montre l'erreur de "écriture invalide à fread" et plusieurs fuites de mémoire en utilisant realloc.Valgrind montrant « écriture invalide de taille 4 à fread » et les fuites mémoire

Voici le code:

bool load(FILE* file, BYTE** content, size_t* length) { 
    // providing default values to content and length 
    *content = NULL; 
    *length = 0; 

    // initializing buffer to hold file data 
    int size = 512; 
    BYTE* buffer = NULL; 
    buffer = malloc(size); 
    if(buffer == NULL) 
     return false; 

    // bytes_read will store bytes read at a time  
    int bytes_read = 0; 

    // reading 512 bytes at a time and incrmenting writing location by 512 
    // reading stops if less than 512 bytes read 
    while((bytes_read = fread(buffer + size - 512 , 1, 512, file)) == 512) 
    { 
     //increasing the size of 
     size = size + 512; 
     if(realloc(buffer,size) == NULL) 
     { 
      free(buffer); 
      return false; 
     } 
    } 

    // undoing final increment of 512 and increasing the size by bytes_read on last iteration 
    size = size - 512 + bytes_read; 

    // triming buffer to minimum size 
    if(size > 0) 
    { 
     BYTE* minimal_buffer = malloc(size + 1); 
     memcpy(minimal_buffer, buffer, size); 
     minimal_buffer[size] = '\0'; 
     free(buffer);  
     *content = minimal_buffer; 
     *length = size; 
     return true; 
    } 

    return false; 
} 

Répondre

3

Votre problème est ici:

if(realloc(buffer,size) == NULL) 

Il réalloue le tampon, mais vous ne sauvegardez pas le nouveau pointeur. La fonction realloc peut allouer une nouvelle zone de mémoire et y copier les données. Il retourne le nouveau pointeur.

Une remarque importante: Ne pas réaffecter au pointeur que vous passez à la fonction realloc, utilisez une variable temporaire. Ensuite, si realloc échoue, vous ne perdrez pas le pointeur d'origine et pourrez nettoyer gracieusement.