-1

请不要轻易按代表减号按钮,我是新来的-请好点

我有 slist.h 由 slist.c 实现

这是 slist.h

    #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.ci 写道

我的问题是,当我调用销毁函数时,我在最后一个节点面临分段错误。我也可以提供我写的 main 。

    #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("in\n");
            temp = dbllist_tail(list);
            printf("out \n");
        }
    //temp = dbllist_head(list);
    //dbllist_remove(list,temp , dealloc);
    //free(temp);
}
//free(current);
//free(temp);

    }

有人可以理解错误并向我解释如何解决它

我现在尝试了几个小时没有成功

4

3 回答 3

1

在这段代码中:

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;
}
于 2013-10-30T21:52:36.920 回答
1

正确答案是:

    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;
    }

在删除功能的头部之前添加这个

由于空指针异常,我在列表头部时做了。谢谢

于 2013-11-05T17:13:13.337 回答
0

在您的 Remove 函数dbllist_remove中,用于 head case 的部分(双关语;))尝试释放为 NULL 且未分配的内存。

参数free(dbllist_data(dbllist_prev(dbllist_head(list))))ANDdbllist_data(dbllist_prev(dbllist_head(list)))将不起作用,因为您已经删除了下一个元素及其指针。它在您的销毁函数中较早地被释放。因此,您不能依赖实际指向任何东西的前一个指针。

所以,我会while在destroy函数中修改你的循环,等到head->nextis null,然后在循环之外简单地删除它,而不使用标准的remove函数。或者修改您的头部案例以考虑何时head->next为空。

于 2013-10-30T22:00:24.433 回答