我试图在C中使用结构的链接列表,其中一个结构代表列表,另一个结构代表列表成员。这是他们的定义:
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;
我的问题是当我尝试释放我分配的内存时。我分配所有它并返回列表的结构,如下所示:
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;
}
因此,初始化头部然后根据我希望列表的大小初始化所有元素。设置next和previous,使previous在开始时为null,next在结尾为null。我的问题真的开始了,当我尝试在使用它之后在一个单独的函数中释放内存:
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);
}
如果我注释掉两个自由语句,代码运行没有问题(我在结构上运行空值后填充操作,并且没有问题),所以这个设置没有问题,直到我尝试释放记忆。我偶尔会遇到运行时错误,可能有50%的时间。
我真的不知道问题是什么,特别是当代码有时无问题地运行而在其他问题上失败时。有人能引导我吗?
答案 0 :(得分:2)
在访问释放指向的内存之前,需要检查NULL指针。
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);
}
}
您还应该检查malloc调用,不要返回NULL。
答案 1 :(得分:0)
SymTab oSymTab = (SymTab)malloc(sizeof(SymTab));
你应该使用struct pointer:
SymTab *oSymTab = (SymTab *)malloc(sizeof(SymTab));
您的所有代码都使用SymTab,将其替换为SymTab *
答案 2 :(得分:0)
所以...首先我要粘贴所有更正的代码,之后我会给你一些错误:
#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);
}