我正在构建一个应该删除链表中项目的函数。我的问题是我可以删除任何元素,但不能删除第一个元素,为什么会这样?
我的目标文件:
typedef struct list {
char *key;
char *value;
struct list *next;
} List;
void db_init(List *list) {
list = malloc(sizeof(db_sizeOfStruct()));
list->next = NULL;
list->key = NULL;
list->value = NULL;
}
void db_delete(char *key, List *list) {
List *prev;
db_init(prev);
int first = 1;
while(list != NULL) {
if(strcmp(key, list->key) == 0) {
if(first == 1) {
list = list->next; // This is supposed to delete the first item in the list but it does not work...
} else {
prev->next = list->next;
}
return;
} else {
prev = list;
list = list->next;
first = 0;
}
}
}
在程序的主文件中:
void delete(List *list) {
printf("key: ");
char *key;
key = malloc(sizeof(key)+1);
readline(key, 128, stdin);
if(key != NULL) {
db_delete(key, list);
}
}
int main(void) {
delete(list);
return 0;
}
答案 0 :(得分:1)
这里有几个问题
首先,你调用db_init,即使你想删除一个元素也会分配一个元素。
其次,您需要考虑如果第一个元素被删除,您需要返回新的第一个元素的地址,但是使用当前函数,您不需要这样做。
原型应该是这样的
void db_delete(char *key, List **list)
或者可能有点整洁,通过返回第一个元素:
List* db_delete(char *key)
所以函数可能看起来像这样
List* db_delete(const char *key, List *list)
{
// normally it is not a good idea to use an argument
// to a function as a loop variable in a function
// also check arguments to avoid segfaults and
// other headaches
if ( key != NULL && list != NULL )
{
List* cur = list;
List* prev = NULL;
for ( ; cur != NULL; cur=cur->next )
{
// identify if it is the one to delete
if ( !strcmp(key, cur->key) )
{
if ( prev != NULL ) // if not first
{
List* tmp = cur;
prev->next = cur->next;
free(tmp);
return list;
}
else // if first
{
List* tmp = cur;
List* next = cur->next;
free( tmp );
return next;
}
}
}
prev = cur;
}
return list;
}
另一个提示是使用calloc而不是malloc,然后你就不会 需要初始化下一个,因为它们已经是0。
答案 1 :(得分:0)
这是因为你的删除功能无法与调用者通信,列表现在有了新的第一个元素。
最好的解决方法是让它返回列表的新头:
List * db_delete(List *list, const char *key);
答案 2 :(得分:0)
您必须在主页中更改列表变量。如果将指针传递给指向删除函数的指针,例如“delete(List ** list)”
,则可以实现这一点