-1

担当者のマイナス ボタンを押さないでください。

私はslist.cによってslist.hを実装しています

ここに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が書いた

私の問題は、最後のノードでセグメンテーション違反に直面している破棄関数を呼び出すときです..私も書いたメインを提供できます。

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

これを remove 関数の head 部分の前に追加します

リストの先頭にあるときに行ったヌルポインター例外のため。ありがとう

于 2013-11-05T17:13:13.337 に答える
0

あなたのRemove関数dbllist_removeでは、ヘッドケース用のセクション(しゃれた意図;))は、NULLで割り当てられていないメモリを解放しようとします。

次の要素とそのポインターを既に削除しているため、引数free(dbllist_data(dbllist_prev(dbllist_head(list))))ANDdbllist_data(dbllist_prev(dbllist_head(list)))は機能しません。これは、destroy 関数で以前に解放されました。したがって、前のポインターが実際に何かを指しているとは限りません。

したがって、destroy 関数のループを変更して、それwhileまで待機し、ループの外で単純に削除し、標準の削除関数を使用しません。または、がnullの場合を考慮してヘッドケースを変更します。head->nextnullhead->next

于 2013-10-30T22:00:24.433 に答える