我已经构建了一个函数,可以将节点插入到双向链接列表中。该结构包括2个字符串,为此我在函数内部动态分配空间。根据Valgrind,这会导致内存泄漏。这是我的代码的简化版本:
typedef struct Node {
char *str1, *str2;
Node *next, *prev;
};
void add(Node* list, char* string1, char* string2) {
Node* temp = list;
Node* new_node = (Node*) malloc(sizeof(Node));
if (!new_node) return;
new_node->str1 = (char*) malloc(30*sizeof(char));
new_node->str2 = (char*) malloc(30*sizeof(char));
strcpy(new_player->str1, string1);
strcpy(new_player->str2, string2);
if (!temp) {
temp = new_node;
new_node->prev = new_node->next = NULL;
new_node = NULL;
free(new_node);
return;
} else {
while (temp->next) temp = temp->next;
new_node->prev = temp;
new_node->next = NULL;
temp->next =new_node;
new_node = NULL;
free(new_node);
}
void destroy(Node* list) {
Node* temp;
while (list) {
temp = list->next;
free(list->str1);
free(list->str2);
free(list);
list = temp;
}
}
在使用完列表之后,我正在main()内部使用destroy函数。这还不够吗?我是否应该以某种方式释放add函数中的字符串?
我在程序中反复使用此功能,因此会造成大约10.0000字节的丢失。您能告诉我为什么会发生这种内存泄漏吗?如何消除它?
答案 0 :(得分:0)
您的add
函数malloc
是Node
,将其链接到列表,然后出于某种原因free
是分配的Node
。这样会将悬空的指针留在列表中。
您的add
函数也没有机制将第一个Node
添加到空白列表。有两种方法可以做到这一点。第一种方法是将指针返回到列表的第一个节点:
Node* add(Node* list, char* string1, char* string2) {
Node* temp = list;
Node* new_node = malloc(sizeof(Node));
if (!new_node) return NULL;
new_node->str1 = malloc(strlen(string1)+1);
new_node->str2 = malloc(strlen(string2)+1);
if (!new_node->str1 || !new_node->str2) {
// allocation error for one of the strings
free(new_node->str1);
free(new_node->str2);
free(new_node);
return NULL;
}
strcpy(new_node->str1, string1);
strcpy(new_node->str2, string2);
new_node->next = NULL;
if (!temp) {
new_node->prev = NULL;
list = new_node;
} else {
while (temp->next) temp = temp->next;
new_node->prev = temp;
temp->next = new_node;
}
// return pointer to first node
return list;
}
使用第一种方法的示例调用:
Node* mylist = NULL;
...
mylist = add(mylist, "hello", "world");
第二种方法是将第一个参数更改为指向列表开头的指针:
void add(Node** list, char* string1, char* string2) {
Node* temp = *list;
Node* new_node = malloc(sizeof(Node));
if (!new_node) return;
new_node->str1 = malloc(strlen(string1)+1);
new_node->str2 = malloc(strlen(string2)+1);
if (!new_node->str1 || !new_node->str2) {
// allocation error for one of the strings
free(new_node->str1);
free(new_node->str2);
free(new_node);
return;
}
strcpy(new_node->str1, string1);
strcpy(new_node->str2, string2);
new_node->next = NULL;
if (!temp) {
new_node->prev = NULL;
*list = new_node;
} else {
while (temp->next) temp = temp->next;
new_node->prev = temp;
temp->next = new_node;
}
}
使用第二种方法的示例调用:
Node* mylist = NULL;
...
add(&mylist, "hello", "world");