释放链表中的 strdup
Freeing a strdup inside of a linked list
我有一个链接列表,我试图在其中释放一个 char*
,我将其用于 strdup
。
这些是我将节点添加到列表中的方法:
node* add_first(char* name, node* head) {
node* new_node;
new_node = (node*)malloc(sizeof(node));
char* c = strdup(name);
new_node->name = c;
new_node->next = head;
head = new_node;
return head;
}
node * add_last(char* name, node *head ) {
node* new_node;
node* current;
new_node = (node*)malloc(sizeof(node));
char* c = strdup(name);
new_node->name = c;
new_node->next = NULL;
if ( head == NULL ){
head = new_node;
}
else{
current = head;
while ( current->next ) current = current->next;
current->next = new_node;
}
return head;
}
删除节点:
int remove_last( node **head, char **ret )
{
int result = *head == NULL ? -1 : 0;
if ( result == 0 )
{
while( ( *head )->next != NULL ) head = &( *head )->next;
*ret = strdup( ( *head )->name );
free( *head );
*head = NULL;
}
return result;
}
清理列表:
void deleteList(node** head){
node* current = *head;
node* next;
while(current != NULL){
next = current->next;
free(current->name);
free(current);
current = next;
}
*head = NULL;
}
但是 valgrind 说,当涉及到 strdup
我的 add_last
函数(但奇怪的是我的 add_first
函数没有)时,我“肯定失去了”记忆。
为什么它只发生在 add_last
方法中,我该如何正确释放它?我以为我正在释放 deleteList
方法中的所有节点和名称?
您不必要地复制了最后一个节点删除算法中的字符串,并泄露了原始字符串。该算法应该找到列表中的最后一个节点,将 name
指针的所有权传递给输出参数,然后删除节点 而不会 删除名称(因为输出 -参数现在拥有它)。
即您应该按照这些思路做一些事情(公平警告,未经编译测试,但希望您能理解):
int remove_last( node **head, char **ret )
{
int res = -1;
if (*head)
{
// find last node in the list
while ((*head)->next)
head = &(*head)->next;
// out-param takes ownership
*ret =(*head)->name;
// free last node *without* freeing the string
free(*head);
*head = NULL;
// result indicates success
res = 0;
}
return res;
}
我有一个链接列表,我试图在其中释放一个 char*
,我将其用于 strdup
。
这些是我将节点添加到列表中的方法:
node* add_first(char* name, node* head) {
node* new_node;
new_node = (node*)malloc(sizeof(node));
char* c = strdup(name);
new_node->name = c;
new_node->next = head;
head = new_node;
return head;
}
node * add_last(char* name, node *head ) {
node* new_node;
node* current;
new_node = (node*)malloc(sizeof(node));
char* c = strdup(name);
new_node->name = c;
new_node->next = NULL;
if ( head == NULL ){
head = new_node;
}
else{
current = head;
while ( current->next ) current = current->next;
current->next = new_node;
}
return head;
}
删除节点:
int remove_last( node **head, char **ret )
{
int result = *head == NULL ? -1 : 0;
if ( result == 0 )
{
while( ( *head )->next != NULL ) head = &( *head )->next;
*ret = strdup( ( *head )->name );
free( *head );
*head = NULL;
}
return result;
}
清理列表:
void deleteList(node** head){
node* current = *head;
node* next;
while(current != NULL){
next = current->next;
free(current->name);
free(current);
current = next;
}
*head = NULL;
}
但是 valgrind 说,当涉及到 strdup
我的 add_last
函数(但奇怪的是我的 add_first
函数没有)时,我“肯定失去了”记忆。
为什么它只发生在 add_last
方法中,我该如何正确释放它?我以为我正在释放 deleteList
方法中的所有节点和名称?
您不必要地复制了最后一个节点删除算法中的字符串,并泄露了原始字符串。该算法应该找到列表中的最后一个节点,将 name
指针的所有权传递给输出参数,然后删除节点 而不会 删除名称(因为输出 -参数现在拥有它)。
即您应该按照这些思路做一些事情(公平警告,未经编译测试,但希望您能理解):
int remove_last( node **head, char **ret )
{
int res = -1;
if (*head)
{
// find last node in the list
while ((*head)->next)
head = &(*head)->next;
// out-param takes ownership
*ret =(*head)->name;
// free last node *without* freeing the string
free(*head);
*head = NULL;
// result indicates success
res = 0;
}
return res;
}