Ошибки Valgrind для использования free () в связанном списке - PullRequest
2 голосов
/ 07 июня 2019

Я делаю проект с использованием хеш-массива.Я помещаю изображение, которое я нашел в Интернете, чтобы показать вам, ребята, что я пытаюсь сделать. image

Итак, я инициализировал большой массив слева следующим образом:

cellule_t * array[HASH_MAX] = {NULL};

Затем я сделал все вставки для создания связанных списков.,Что я хочу сделать сейчас, это освободить () всю память, выделенную для создания всего этого.Итак, как будто я не использую malloc для большого массива, мне просто нужно освободить связанные списки, и я использую эту функцию:

Но я получаю некоторые ошибки от Valgrind, и блоки не освобождаются.Я помещаю все функции, которые я использую, включая главную, чтобы сделать ее более понятной.

typedef struct cell{

   char *mot;
   char *traduction;
   struct cell *suivant;

}cellule_t;

int main()
{
int indice;
cellule_t *cel;
FILE*file = NULL;
char buffer[100] = "hello bye glass sorry";    
cellule_t *tabMajeur[HASH_MAX] = {0};
file = fopen("fichier.txt","r");
remplissage_hachage(tabMajeur,file);    (c:157)
affichageTraduction(tabMajeur,buffer);
libererMemorie(tabMajeur);  (c:159)

}

void remplissage_hachage (cellule_t **tabMajeur,FILE *fichier)
{
char  string1[20];
unsigned int indice = 0;
cellule_t *copy;
int boolean = 0;
char *string2, *string3 = NULL;
cellule_t *c =NULL;


while(fgets(string1,100,fichier) != NULL)
{
    string2 = strtok(string1,";");
    string3 = strtok(NULL,";"); 
    string3[strlen(string3)-1] = '\0';
    printf("string2 %s\n",string2);
    printf("string3 %s\n",string3);
    indice = hash_string(string2);
    boolean = 0;
    indice = recherche(tabMajeur,string2,&boolean,&c);

    if(boolean != 1) 
    {
        copy = tabMajeur[indice];
        tabMajeur[indice] = creationCellule(string2,string3); (c: 64)
        tabMajeur[indice]->suivant = copy;    
    }
}


}



cellule_t* creationCellule(char * mot, char *traduction)
{

  cellule_t *nouveau = (cellule_t *) malloc(sizeof(cellule_t)); (c:24)

  if(nouveau != NULL)
  {
    nouveau -> mot = strdup(mot);
    nouveau -> traduction = strdup(traduction);
    nouveau -> suivant = NULL;
  }

  return nouveau;

}



void libererMemorie(cellule_t **tabMajeur)
{

int i = 0;
cellule_t * cour;
cellule_t * copy;
for(i = 0 ; i < HASH_MAX; i++)
{
    cour = tabMajeur[i];
    while(cour != NULL)
    {
        copy = cour;
        free(copy); (c:137)
        cour = cour->suivant; (c:138)
    }

}
}

Ошибка valgrind: введите описание изображения здесь

Текстдля valgrind ошибка:

==2550== Memcheck, a memory error detector
==2550== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2550== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2550== Command: ./tp4
==2550== 
string2 hello
string3 bonjour
string2 bye
string3 au revoir
string2 sorry
string3 pardon
string2 glass
string3 verre
La traduction est bonjour au revoir verre pardon 
==2550== Invalid read of size 8
==2550==    at 0x108E55: libererMemorie (tp4.c:138)
==2550==    by 0x108F85: main (tp4.c:159)
==2550==  Address 0x522ea40 is 16 bytes inside a block of size 24 free'd
==2550==    at 0x4C30D3B: free (in 
   /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
 ==2550==    by 0x108E50: libererMemorie (tp4.c:137)
==2550==    by 0x108F85: main (tp4.c:159)
 ==2550==  Block was alloc'd at
==2550==    at 0x4C2FB0F: malloc (in 
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
 ==2550==    by 0x108A5D: creationCellule (tp4.c:24) 
 ==2550==    by 0x108BD8: remplissage_hachage (tp4.c:64)
==2550==    by 0x108F60: main (tp4.c:157)
==2550== 
==2550== 
==2550== HEAP SUMMARY:
==2550==     in use at exit: 605 bytes in 9 blocks
==2550==   total heap usage: 15 allocs, 6 frees, 5,821 bytes allocated
==2550== 
==2550== LEAK SUMMARY:
==2550==    definitely lost: 53 bytes in 8 blocks
==2550==    indirectly lost: 0 bytes in 0 blocks
==2550==      possibly lost: 0 bytes in 0 blocks
==2550==    still reachable: 552 bytes in 1 blocks
==2550==         suppressed: 0 bytes in 0 blocks
==2550== Rerun with --leak-check=full to see details of leaked memory
==2550== 
==2550== For counts of detected and suppressed errors, rerun with: -v
==2550== ERROR SUMMARY: 4 errors from 1 contexts (suppressed: 0 from 0)

Можете ли вы помочь мне выяснить, в чем дело?

1 Ответ

1 голос
/ 07 июня 2019

Ошибка «Недопустимое чтение» может быть связана с тем, что, хотя у вас есть односвязный список для каждого сегмента в вашей хэш-таблице, вы пытаетесь освободить узел списка и затем получить доступ к указателю на следующий узел после того, как вы освободил текущий узел.

Так что в основном здесь:

copy = cour;
free(copy);
cour = cour->suivant;

Вы создаете неопределенное поведение, потому что вы освобождаете узел, затем пытаетесь получить доступ к свободной памяти через указатель cour, чтобы перейти к следующему указателю в связанном списке. Присваивая copy значение cour, копируется только само значение указателя. Затем вы освобождаете память, указанную copy и cour, а затем пытаетесь получить доступ к памяти в свободном блоке. Вальгринду это точно не понравится.

Вы можете просто изменить свой заказ на следующее:

copy = cour;
cour = cour->suivant;
free(copy);

Теперь вы освобождаете память в текущем узле после копирования копии указателя на следующий узел, пока блок памяти все еще является допустимым выделенным блоком памяти.

...