I am coding a hash table with singly linkedList and I have this problem free(): double free detected in tcache 2 I tried to fix it but did'nt make it, the problem its the free() , so could you explain me why I have it, So if anyone can help, so please help me, I'm trying to fix it for hours now...
Thank you.
I've watched some video on youtube and many topics on websitte and also here but I didn't find a solution for mine.
This are my functions:
/**List header */
#ifndef LISTE_H
#define LISTE_H
struct _list_node {
void * data;
struct _list_node *next;
};
typedef struct _list_node s_node;
s_node * list_create(void);
void * list_get_data(s_node * node);
void list_set_data(s_node * node, void * data);
s_node * list_insert(s_node * head, void * data);
s_node * list_append(s_node * head, void * data);
int list_process(s_node * head, int (*fct)(s_node * node, void * param),
void * param, s_node ** last);
s_node * list_ordered_append(s_node ** head, int (*fct)(s_node * node, void * param),
void * param);
s_node * list_remove (s_node * head, void * data);
s_node * list_headRemove(s_node * head);
void * list_destroy(s_node * head);
void afficher_s_node(s_node * list);
int list_is_empty( s_node * node );
unsigned int list_size(s_node * node);
int list_process(s_node * head, int (*fct)(s_node * node, void * param),
void * param, s_node ** last);
#endif
/**** c file list */
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
s_node * list_create(void)
{
return NULL;
}
void * list_get_data(s_node * node)
{
return node->data;
}
void list_set_data(s_node * node, void * data)
{
node->data = data;
}
s_node * list_insert(s_node * head, void * data)
{
s_node * node = (s_node *) malloc(sizeof(s_node));
list_set_data(node, data);
node->next = head;
return node;
}
s_node * list_append(s_node * head, void * data)
{
if (!head) return list_insert(head, data);
s_node * node = head;
while (node->next) {
node = node->next;
}
node->next = (s_node *) malloc(sizeof(s_node));
node->next->next = list_create();
list_set_data(node->next, data);
return head;
}
int list_process(s_node * head, int (*fct)(s_node * node, void * param),
void * param, s_node ** last)
{
if (!head) return 0;
s_node * node;
for (node = head; node; node = node->next) {
if (fct(node, param) == 1) {
*last = node;
return 1;
}
}
return 0;
}
s_node * list_ordered_append(s_node ** head, int (*fct)(s_node * node, void * param),
void * param)
{
// quand elle est vide
if (!(*head)) {
*head = list_insert(*head, param);
return *head;
}
// insertion en tete
s_node * node;
if (fct(*head, param) == 1) {
*head = list_insert(*head, param);
return (*head);
}
// cas general
int res;
for(node = *head; node->next; node = node->next) {
if ((res = fct(node->next, param)) == 1) {
node->next = list_insert(node->next, param);
return node->next;
} else if (res == 0) {
return node->next;
}
}
if (fct(node, param) == 0) return node;
*head = list_append(*head, param);
return node->next;
}
s_node * list_remove (s_node * head, void * data)
{
if (!head) return head;
for (s_node * node = head; node->next; node = node->next) {
if (node->next->data == data) {
s_node * n = node->next->next;
free(node->next);
node->next = n;
break;
}
}
return head;
}
s_node * list_headRemove(s_node * head)
{
if (!head) return head;
s_node * n = head->next;
free(head);
return n;
}
void * list_destroy(s_node * head)
{
while (head)
head = list_headRemove(head);
}
void afficher_s_node(s_node * list)
{
printf("\nliste = [");
while (list) {
printf("%d,", *((int *)(list->data)));
list = list->next;
}
printf("]\n");
return;
}
int list_is_empty( s_node * node ) {
return NULL == node;
}
unsigned int list_size(s_node * node)
{
unsigned int i = 0;
while (node) {
node = node->next;
i++;
}
return i;
}
/*PLUS
int list_process(s_node * head, int (*fct)(s_node * node, void * param),
void * param, s_node ** last)
{
if (!head) return 0;
s_node * node;
for (node = head; node; node = node->next) {
if (fct(node, param) == 1) {
*last = node;
return 1;
}
}
return 0;
}
*/
/* hash table header */
#ifndef HACHAGE_H
#define HACHAGE_H
#include "list.h"
typedef struct {
s_node * node;
unsigned int len;
} super_list;
typedef struct {
super_list * list;
unsigned int len;
} strhash_table;
strhash_table * strhash_table_init(const unsigned int len);
strhash_table * strhash_table_destroy(strhash_table * table);
strhash_table * strhash_table_free(strhash_table * table);
char * strhash_table_add(strhash_table * table, char * str);
strhash_table * strhash_table_remove(strhash_table * table, char * str);
void strhash_table_info(strhash_table * table);
void strhash_print(strhash_table * table);
#endif
/**** c file hash table */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "hachage.h"
#include "list.h"
int hashCode(char * str, const int size_hash_table)
{
int i, cle = 0;
for (i = 0; str[i] != '\0'; i++) {
cle *= 2;
cle += (int) str[i];
}
return cle % size_hash_table;
}
int compare_str_add(s_node *node, void *param)
{
int res = strcmp((char *) node->data, (char *) param);
/*if the first non-matching character in node->data
is lower (in ASCII) than that of param.*/
if (res < 0) return -1;
/*if the first non-matching character in node->data
is greater (in ASCII) than that of param.*/
if (res > 0) return 1;
return 0;//if strings are equal
}
strhash_table * strhash_table_init(const unsigned int len)
{
super_list *list = (super_list *) malloc(sizeof(super_list) * len);
strhash_table * table = (strhash_table *) malloc(sizeof(strhash_table));
if(!table) return NULL;
table->len = len;
if (!list) return NULL;
for (unsigned int i = 0; i < len; i++) {
list[i].node = list_create();
list[i].len = 0;
}
table->list = list;
return table;
}
strhash_table * strhash_table_destroy(strhash_table * table)
{
unsigned int i;
super_list *list;
s_node *node, *next;
for (i = 0; i < table->len; i++) {
list = table->list + i;
node = list->node;
while (node) {
next = node->next;
free(node->data);
free(node);
node = next;
}
}
free(table->list);
free(table);
return table;
}
strhash_table * strhash_table_free(strhash_table * table)
{
unsigned int i;
super_list *list;
for (i = 0; i < table->len; i++) {
list = table->list + i;
if (list->len > 0) {
free(list->node->data);
list_destroy(list->node);
list->len = 0;
return table;
}
}
return table;
}
char * strhash_table_add(strhash_table * table, char * str)
{
char * to_insert = strdup(str);
int index = hashCode(str, table->len);
s_node *ordered_Add = list_ordered_append(&(table->list[index].node), compare_str_add, to_insert);
if (ordered_Add->data == to_insert)
table->list[index].len++;
else
free(to_insert);
return (char *) ordered_Add->data;
}
int find_str_node(s_node *node, void *param)
{
return strcmp((char *) node->data, (char *) param) == 0 ? 1 : 0;
}
strhash_table * strhash_table_remove(strhash_table * table, char * str)
{
const int index = hashCode(str, table->len);
if (table->list[index].len == 0) return table;
s_node *find_node;
const int result = list_process(table->list[index].node, &find_str_node, str, &find_node);
if (result == 1) {
free(find_node->data);
table->list[index].node = list_remove(table->list[index].node, find_node->data);
table->list[index].len--;
}
return table;
}
void strhash_table_info(strhash_table * table)
{
unsigned int i;
unsigned int len, min, max;
float deviation, moy;
len = max = min = table->list[0].len;
for (i = 1; i < table->len; i++) {
if (table->list[i].len > max) max = table->list[i].len;
else if (table->list[i].len < min) min = table->list[i].len;
len += table->list[i].len;
}
moy = (float)len / table->len;
deviation = 0;
for (i = 0; i < table->len; i++) {
deviation += (table->list[i].len - moy) * (table->list[i].len - moy);
}
deviation = (float) sqrt(deviation / table->len);
printf("Table hachage : ");
printf("%p\n",table);
printf("\tNombre total d'élément : " );
printf("%u\n",len );
printf("\tNombre minimum : ");
printf("%u\n", min);
printf("\tNombre maximum : ");
printf("%u\n", max );
printf("\tÉcart type du nombre d'éléments par entrée : ");
printf("%.2f\n", deviation );
return;
}
void strhash_print(strhash_table * table)
{
unsigned int i, j;
super_list *list;
s_node *node;
printf("\nHash table de %p\n", table);
printf("Start\n");
for (i = 0; i < table->len; i++) {
list = table->list + i;
printf("\t%d ---\n", i);
/****/
for (j = 0, node = list->node; j < list->len; j++, node = node->next)
{
printf( "\t\t%d. %s\n", j, (char *) node->data);
}
}
printf("End\n");
return;
}
/**** test file */
strhash_table * test_init(const unsigned int len)
{
strhash_table * table = strhash_table_init(len);
if (!table) {
printf("Tha HashTable hasn't been created\n");
assert(0);
}
printf("***Tha HashTable has been created***\n");
return table;
}
strhash_table * test_destroy(strhash_table * table){
table = strhash_table_destroy(table);
if (table->list->node) {
printf("The HashTable hasn't been destroyed (%p)\n", table->list->node);
assert(0);
}
printf("The HashTable has been destroyed\n");
return NULL;
}
int main(void)
{
strhash_table * table =strhash_table_init(10);
strhash_print(table);
strhash_table_add(table, "ele1");
strhash_table_add(table, "ele2");
strhash_table_add(table, "ele3");
strhash_table_add(table, "ele4");
strhash_table_add(table, "ele5");
//strhash_table_remove(table,"ele1");
//strhash_table_free(table);
test_destroy(table);
return 0;
}
Thank you in advance ^^