C中的分段错误链表



请不要轻易按下重复减号按钮,我是新的 - 请做好

我有 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为空时。

相关内容

  • 没有找到相关文章

最新更新