C 链表:出列正确返回弹出的数据,但在尝试使用打印时出现分段错误

C 链表:出列正确返回弹出的数据,但在尝试使用打印时出现分段错误,c,data-structures,linked-list,C,Data Structures,Linked List,我正在尝试用C实现一个链表,在大多数情况下,它似乎是可行的。但是,当我尝试使用队列/出列功能时,事情就崩溃了 在下面的调试printf语句中,当我将字符串排队时,要返回的输出能够很好地打印出来。但是当我试图在函数之外使用它时,当它返回时,我最终遇到了一个分段错误 像_next()这样的函数工作得非常好 void* LinkedList_dequeue(LinkedList* list) { Node* beforeNext = NULL;

我正在尝试用C实现一个链表,在大多数情况下,它似乎是可行的。但是,当我尝试使用队列/出列功能时,事情就崩溃了

在下面的调试printf语句中,当我将字符串排队时,要返回的输出能够很好地打印出来。但是当我试图在函数之外使用它时,当它返回时,我最终遇到了一个分段错误

像_next()这样的函数工作得非常好

void* LinkedList_dequeue(LinkedList* list)
{
    Node* beforeNext = NULL;                            //Keep track of node before cursor
    Node* toDelete;                                     //Remember to free memory!
    void* output;

    if(LinkedList_isEmpty(list)){                       //Check if list is empty
        return NULL;                                    //Empty; return NULL
    }else{                                              //List is not empty; continue
        while(LinkedList_isNext(list)){                 //Iterate to end.
            beforeNext = list->cursor;
            LinkedList_next(list);
        }
        output = list->cursor->data;
        toDelete = list->cursor;
        if(beforeNext){                                 //beforeNext is not NULL
            beforeNext->next = NULL;                    //Sever connection
        }else{
            list->cursor = NULL;                        //Else, set cursor to NULL
            list->head   = NULL;
        }

        LinkedList_resetCursor(list);                   //Reset cursor.

        Node_free(toDelete);                            //Clean up
        printf("Output: %s\n", output);                 //TODO DEBUG
        return output;  
    }
}
结构:

/*//////////////////////////////////////////////////////////////////////////*/
/*STRUCT:                                                                   */
/*      LinkedList                                                          */
/*Linked List data structure                                                */
/*                                                                          */
/*Members:                                                                  */
/*      Node* head:                                                         */
/*          The head node of the list                                       */
/*      Node* cursor:                                                       */
/*          Internal pointer                                                */
/*//////////////////////////////////////////////////////////////////////////*/
typedef struct LinkedList{
    Node* head;
    Node* cursor;
} LinkedList;
#endif


/*//////////////////////////////////////////////////////////////////////////*/
/*STRUCT:                                                                   */
/*      Node                                                                */
/*Nodes for LinkedList struct                                               */
/*                                                                          */
/*Members:                                                                  */
/*      Node* next:                                                         */
/*          Appended child node                                             */
/*      void* data:                                                         */
/*          Data held in the node                                           */
/*//////////////////////////////////////////////////////////////////////////*/
typedef struct Node{
    struct Node* next;
    void* data;
} Node;

如果需要我的其余代码,我也可以发布。

我猜是这些行造成的:

output = list->cursor->data;
toDelete = list->cursor;

...

Node_free(toDelete);                            //Clean up
printf("Output: %s\n", output);
首先让
output
指向
cursor->data
,然后释放
cursor
,可能也会释放
data
?在这种情况下,下次取消引用
输出时
将取消引用指向未分配内存的指针,从而导致


简单的解决方案?在释放节点之前打印。

在调试器中运行,以准确了解崩溃发生的位置和时间。让我们看看。。。看起来str_len()正在根据gdb设置segfault。进一步研究,内存似乎无论如何都是不可访问的:
$1=0x1e98
Hmm。也许它以某种方式结束在函数堆栈上,这就是为什么它只能在函数内部打印?因为它会被弹出。哦,那个
printf()
语句实际上工作得很好。调用程序(main)中正在使用一个函数,它试图打印返回的值,但失败了,尽管它在返回前成功打印了行。@SaxOplutist很高兴它能在您的系统上工作。当malloc(3)决定改变它的工作方式时,它可能会立即停止工作,比如在OpenBSD上,
free(3)
覆盖所有已释放的内存或立即将其返回操作系统。