Reputation: 143
I'm trying to use a linked list of structs in C, with one struct representing the list and another representing the members of the list. This is their definition:
typedef struct symEntry symEntry;
struct symEntry{
const char * key;
const void * value;
struct symEntry * next;
struct symEntry * linked;
struct symEntry * previous;
};
typedef struct{
symEntry* head;
symEntry* tail;
int size;
} symTab;
typedef symTab * SymTab;
And my issue is when I try to free the memory I allocate. I allocate all of it and return the struct of the list like so:
SymTab ST_new()
{
SymTab oSymTab = (SymTab)malloc(sizeof(SymTab));
symEntry * head = (symEntry *)malloc(sizeof(symEntry));
head->key = NULL;
head->value = NULL;
head->previous = NULL;
head->linked = NULL;
oSymTab->head = head;
oSymTab->size = 0;
ST_fill(oSymTab, sizeArray[currentSize]);
return oSymTab;
}
void ST_fill(SymTab oSymTab, int size)
{
symEntry * current;
current = oSymTab->head;
int i;
for(i = 0; i < size-1; i++)
{
symEntry * entry = (symEntry *)malloc(sizeof(symEntry));
entry->key = NULL;
entry->value = NULL;
entry->linked = NULL;
entry->previous = current;
current->next = entry;
current = current->next;
}
current->next = NULL;
oSymTab->tail = current;
}
So, initialising the head and then initialising all the elements according to whatever size I want the list to be. Set next and previous, so that previous is null at the start and next is null at the end. My issue really begins when I try to free the memory in a separate function after it's been used:
void ST_free(SymTab oSymTab)
{
symEntry * current;
symEntry * previous;
current = oSymTab->head;
while(current->next != NULL)
{
previous = current;
current= current->next;
free(previous);
}
free(oSymTab);
}
If I comment out both free statements the code runs without issue (I've run operations on the struct after filling it with empty values and it has zero issues), so this set up has no problems until I try to free the memory. I am having runtime errors occasionally, maybe 50% of the time.
I have truly no idea what the issue is, particularly when the code runs without issue at times and fails at others. Would anybody be able to guide me?
Upvotes: 0
Views: 84
Reputation: 31
So ... first I'm going to paste all your corrected code and after that I will mark you some mistakes:
#include <stdlib.h>
typedef struct symEntry symEntry;
struct symEntry{
const char * key;
const void * value;
struct symEntry * next;
struct symEntry * linked;
struct symEntry * previous;
};
typedef struct{
symEntry* head;
symEntry* tail;
int size;
} symTab;
void ST_fill(symTab * oSymTab, int size)
{
symEntry * current;
current = oSymTab->head;
for(int i = 0; i < size-1; i++)
{
symEntry * entry = (symEntry *)malloc(sizeof(symEntry));
entry->key = NULL;
entry->value = NULL;
entry->linked = NULL;
entry->previous = current;
current->next = entry;
current = current->next;
}
current->next = NULL;
oSymTab->tail = current;
}
symTab ST_new()
{
symTab * oSymTab = malloc(sizeof(symTab));
int currentSize = 1;
int sizeArray[currentSize];
symEntry * head = (symEntry *)malloc(sizeof(symEntry));
head->key = NULL;
head->value = NULL;
head->previous = NULL;
head->linked = NULL;
oSymTab->head = head;
oSymTab->size = 0;
ST_fill(oSymTab, sizeArray[currentSize]);
return * oSymTab;
}
void ST_free(symTab * oSymTab)
{
symEntry * current;
symEntry * previous;
current = oSymTab->head;
while(current->next != NULL)
{
previous = current;
current= current->next;
free(previous);
}
free(oSymTab);
}
Upvotes: 0
Reputation: 51
SymTab oSymTab = (SymTab)malloc(sizeof(SymTab));
You should use struct pointer:
SymTab *oSymTab = (SymTab *)malloc(sizeof(SymTab));
All of your code are use SymTab, replace them by SymTab *
Upvotes: 0
Reputation: 971
You need to check for NULL pointers before accessing of freeing the memory pointed to.
void ST_free(SymTab oSymTab)
{
if (oSymTab != NULL)
{
symEntry * current;
symEntry * previous;
current = oSymTab->head;
while(current != NULL && current->next != NULL)
{
previous = current;
current= current->next;
free(previous);
}
free(oSymTab);
}
}
You should also check you malloc calls don't return NULL.
Upvotes: 2