请不要轻易按下重复减号按钮,我是新的 - 请做好
我有 slist.h 通过 slist.c 实现
这是列表。
#ifndef DBLLIST_H
#define DBLLIST_H
//! The definition of a double linked list node
typedef struct dbllist_node
{
void *data; // Pointer to data of this node
struct dbllist_node *next; // Pointer to next node on list
struct dbllist_node *prev; // Pointer to previous node on list
}dbllist_node_t;
//! The definition of a double linked list
struct dbllist
{
dbllist_node_t *head; // Pointer to head of list
dbllist_node_t *tail; // Pointer to tail of list
unsigned int size; // The number of elements in the list
};
//! double linked list type
typedef struct dbllist dbllist_t;
// you have to use these macros, do not use the inner variables of the list!!
//! Macro to get the head node of a list l
#define dbllist_head(l) l->head
//! Macro to get the tail node of a list l
#define dbllist_tail(l) l->tail
//! Macro to get the size of a list l
#define dbllist_size(l) l->size
//! Macro to get the next node of l
#define dbllist_next(n) n->next
//! Macro to get the prev node of l
#define dbllist_prev(n) n->prev
//! Macro to get the data of node l
#define dbllist_data(n) n->data
//! Specifies whether dbllist_destroy should deallocate or not stored elements
typedef enum { DBLLIST_LEAVE_DATA = 0, DBLLIST_FREE_DATA } dbllist_destroy_t;
/** Initialize a double linked list
param list - the list to initialize */
void dbllist_init(dbllist_t *);
/** Destroy and de-allocate the memory hold by a list
param list - a pointer to an existing list
param dealloc flag that indicates whether stored data should also be de-allocated */
void dbllist_destroy(dbllist_t *,dbllist_destroy_t);
/** Append data to list (add as last node of the list)
param list - a pointer to a list
param data - the data to place in the list
return 0 on success, or -1 on failure */
int dbllist_append(dbllist_t *,void *);
/** Prepend data to list (add as first node of the list)
param list - a pointer to list
param data - the data to place in the list
return 0 on success, or -1 on failure
*/
int dbllist_prepend(dbllist_t *,void *);
/** brief Remove the specific node from the list.
param to a pointer to the list
param pointer to the node that should be removed.
param dealloc flag that indicates whether to de-allocated the data in the node
return 0 on success, or -1 on failure
*/
int dbllist_remove(dbllist_t *, dbllist_node_t* ,dbllist_destroy_t);
#endif
现在我写的slist.c
我的问题是当我调用销毁函数时,我在最后一个节点面临分段错误......我也可以提供我写的主节点。
#include "slist.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void dbllist_init(dbllist_t *list)
{ if(list != NULL)
{
dbllist_head(list) = NULL;
dbllist_tail(list) = NULL;
dbllist_size(list) = 0;
}
}
int dbllist_append(dbllist_t *list,void *data)
{
dbllist_node_t *temp = (dbllist_node_t *)malloc(sizeof(dbllist_node_t));
if(temp == NULL)
return -1;
dbllist_data(temp) = data;
if(list!=NULL)
{
if(dbllist_head(list) == NULL)
{
//dbllist_next(temp) = NULL;
dbllist_prev(temp) = NULL;
dbllist_head(list) = temp;
dbllist_tail(list) = temp;
dbllist_size(list)++;
return 0;
}
else
{
dbllist_next(temp) = NULL;
dbllist_prev(temp) = dbllist_tail(list);
dbllist_next(dbllist_tail(list)) = temp;
dbllist_tail(list) = temp;
dbllist_size(list)++;
return 0;
}
}
return -1;
}
int dbllist_prepend(dbllist_t *list,void *data)
{
dbllist_node_t *temp = (dbllist_node_t *)malloc(sizeof(dbllist_node_t));
if(temp == NULL)
return -1;
dbllist_data(temp) = data;
if(list!=NULL)
{
if(dbllist_head(list) == NULL)
{
//dbllist_next(temp) = NULL;
dbllist_prev(temp) = NULL;
dbllist_head(list) = temp;
dbllist_tail(list) = temp;
dbllist_size(list)++;
return 0;
}
else
{
dbllist_next(temp) = dbllist_head(list) ;
dbllist_prev(temp) = NULL;
dbllist_prev(dbllist_head(list)) = temp;
dbllist_head(list) = temp;
dbllist_size(list)++;
return 0;
}
}
return -1;
}
/**
int dbllist_remove(dbllist_t *list, dbllist_node_t* pointer,dbllist_destroy_t dealloc)
{
dbllist_node_t *temp = (dbllist_node_t *)malloc(sizeof(dbllist_node_t));
if(temp == NULL)
return -1;
temp = dbllist_head(list);
if(list != NULL && pointer !=NULL)
{
if(pointer == dbllist_head(list))
{
if(dealloc != DBLLIST_LEAVE_DATA)
free(dbllist_data(pointer));
dbllist_head(list) = NULL;
dbllist_size(list) = 0;
dbllist_tail(list) = NULL;
free(dbllist_head(list));
free(temp);
return 0;
}
if(pointer == dbllist_tail(list))
{
dbllist_tail(list) = dbllist_prev(dbllist_tail(list)) ;
dbllist_next(dbllist_tail(list)) = NULL;
if(dealloc != DBLLIST_LEAVE_DATA)
free(dbllist_data(pointer));
free(temp);
free(pointer);
dbllist_size(list)--;
return 0 ;
}
int tempSize = 1;
for(temp = dbllist_next(temp) ; tempSize< dbllist_size(list); temp = dbllist_next(temp),tempSize++)
if(temp == pointer)
{
dbllist_next(dbllist_prev(temp)) = dbllist_next(temp);
dbllist_prev(dbllist_next(temp)) = dbllist_prev(temp);
if(dealloc != DBLLIST_LEAVE_DATA)
free(dbllist_data(pointer));
free(temp);
free(pointer);
dbllist_size(list)--;
return 0;
}
}
return -1;
}
*/
int dbllist_remove(dbllist_t *list, dbllist_node_t* pointer,dbllist_destroy_t dealloc)
{
if(list == NULL || pointer == NULL )
return -1;
//printf("%d n",(int)dbllist_data(current));
if( pointer == dbllist_head(list))
{
dbllist_head(list) = dbllist_next(dbllist_head(list));
if(dealloc == DBLLIST_FREE_DATA)
free(dbllist_data(dbllist_prev(dbllist_head(list))));
free(dbllist_prev(dbllist_head(list)));
dbllist_prev(dbllist_head(list)) = NULL;
dbllist_size(list)--;
return 0;
}
if(pointer == dbllist_tail(list))
{
dbllist_tail(list) = dbllist_prev(dbllist_tail(list));
if(dealloc == DBLLIST_FREE_DATA)
free(dbllist_data(dbllist_next(dbllist_tail(list))));
free(dbllist_next(dbllist_tail(list)));
dbllist_next(dbllist_tail(list)) = NULL;
dbllist_size(list)--;
return 0;
}
//int i = 1;
dbllist_node_t *current = dbllist_next(dbllist_head(list));
while(current)
{
if(current == pointer)
{
dbllist_next(dbllist_prev(current)) = dbllist_next(current) ;
dbllist_prev(dbllist_next(current)) = dbllist_prev(current) ;
dbllist_size(list)--;
if(dealloc == DBLLIST_FREE_DATA)
free(dbllist_data(current));
free(current);
current = NULL;
return 0;
}
current = dbllist_next(current);
}
free(current);
return -1;
}
void dbllist_destroy(dbllist_t *list ,dbllist_destroy_t dealloc)
{
//dbllist_node_t *current = (dbllist_node_t *)malloc(sizeof(dbllist_node_t));
//dbllist_node_t *temp = (dbllist_node_t *)malloc(sizeof(dbllist_node_t));
while (dbllist_head(list) != NULL)
{
//dbllist_node_t *current;
dbllist_node_t *temp ;
temp = dbllist_tail(list);
while(temp)
{
dbllist_remove(list,temp , dealloc);
printf("inn");
temp = dbllist_tail(list);
printf("out n");
}
//temp = dbllist_head(list);
//dbllist_remove(list,temp , dealloc);
//free(temp);
}
//free(current);
//free(temp);
}
有人可以理解错误并向我解释如何解决它吗
我现在尝试了几个小时没有成功
在此代码中:
if( pointer == dbllist_head(list))
{
// After next line: list->head points to next node (could be null)
dbllist_head(list) = dbllist_next(dbllist_head(list));
if(dealloc == DBLLIST_FREE_DATA)
// -- If head is now NULL, what happens below? --
free(dbllist_data(dbllist_prev(dbllist_head(list))));
free(dbllist_prev(dbllist_head(list)));
dbllist_prev(dbllist_head(list)) = NULL;
dbllist_size(list)--;
return 0;
}
正确的答案是:
if(!dbllist_next(dbllist_head(list)))
{
if(dealloc == DBLLIST_FREE_DATA )
free(dbllist_data(dbllist_head(list)));
free(dbllist_head(list));
dbllist_head(list) = NULL;
dbllist_size(list)--;
return 0;
}
在删除功能中的头部之前添加此内容
由于我在列表头部时执行的空指针异常。谢谢
在 Remove 函数中dbllist_remove
用于头部大小写的部分(双关语意图;))尝试释放 NULL 且未分配的内存。
参数free(dbllist_data(dbllist_prev(dbllist_head(list))))
AND dbllist_data(dbllist_prev(dbllist_head(list)))
将不起作用,因为您已经删除了下一个元素及其指针。它之前在您的销毁函数中被释放。因此,您不能依赖前面的指针实际指向任何内容。
因此,我会修改 destroy 函数中的 while
循环,以等到head->next
null
,然后简单地将其删除到循环之外,而不使用标准的 remove 函数。或者修改您的头部大小写以考虑head->next
为空时。