【问题标题】:C: Segfault when deleting first item in Doubly Linked ListC:删除双向链表中的第一项时出现段错误
【发布时间】:2014-06-02 10:45:02
【问题描述】:

对于课程,我要编写一个程序来处理数据并将其分类到单独的列表中。

到目前为止,我创建了一个列表来保存数据,然后为每个单独的“客户”及其“购买的书籍”创建了一个列表数组。

尝试从列表中删除第一项时遇到段错误。

Please enter the name of your input file.
input1.txt
Reading in: 'input1.txt'
5 10 1 407 2 8127 1 8131 4 22048 5 407 3 64 5 22026 2 19 1 406 3 162779
Just created 5 lists.
Customer ID: 1   BookID: 407
2 8127 1 8131 4 22048 5 407 3 64 5 22026 2 19 1 406 3 162779
Customer ID: 2   BookID: 8127
1 8131 4 22048 5 407 3 64 5 22026 2 19 1 406 3 162779
Customer ID: 1   BookID: 8131
4 22048 5 407 3 64 5 22026 2 19 1 406 3 162779
Customer ID: 4   BookID: 22048
5 407 3 64 5 22026 2 19 1 406 3 162779
Customer ID: 5   BookID: 407
3 64 5 22026 2 19 1 406 3 162779
Customer ID: 3   BookID: 64
5 22026 2 19 1 406 3 162779
Customer ID: 5   BookID: 22026
2 19 1 406 3 162779
Customer ID: 2   BookID: 19
1 406 3 162779
Customer ID: 1   BookID: 406
3 162779
Customer ID: 3   BookID: 162779
List is empty.

Segmentation fault (core dumped)

这是我在 main 中的代码:

//  Create x amount of array with x being the first number in 'holder'.
ListHndl list[getFirst(holder)];
int i;
for (i = 1; i <= getFirst(holder); i++) {
    list[i] = newList();
}
printf("Just created %d lists.\n", getFirst(holder));


deleteFirst(holder); // Delete the # of customers
deleteFirst(holder); // Delete the # of purchases

//  Iterate and process 'holder'.
long customer, bookID;
while (!isEmpty(holder)) {
    customer = getFirst(holder);
    deleteFirst(holder);
    bookID = getFirst(holder);
    deleteFirst(holder);
    printf("Customer ID: %d\t BookID: %d\n",customer, bookID);
    // insertOrder(list[customer], bookID);
    printList(NULL, holder);
}

这是 list.h 的一部分:

typedef struct NodeStruct {
        long data;
        struct NodeStruct* next;
        struct NodeStruct* prev;
} NodeStruct;

//      Rename NodeStruct* as NodePtr
typedef NodeStruct* NodePtr;

typedef struct ListStruct {
        NodePtr first;
        NodePtr last;
        NodePtr current;
} ListStruct;

//      ListHndl is just a ListStruct* renamed.

这里是 deleteFirst 函数:

void deleteFirst(ListHndl L) {
        assert (!isEmpty(L));
        NodePtr tmp = L->first;
        if(L->first->next == NULL)
            L->last = NULL;
        else L->first->next->prev = NULL;
        L->first = L->first->next;
        free(tmp);

}

这里是 insertSort 函数。

void insertOrder(ListHndl L, long data) {

        NodePtr tmp = newNode();
    tmp->data = data;

    NodePtr prev = NULL;
    NodePtr curr = L->first;

    while (curr != NULL && data > curr->data) {
        prev = curr;
        curr = curr->next;
    }
    if (curr == NULL) L->last = tmp;
    if (prev == NULL) L->first = tmp;
    else prev->next = tmp;
    tmp->next = curr;

}

有什么想法吗?谢谢。 这就是 valgrind 显示的内容:

==498== Invalid read of size 8
==498==    at 0x400D41: getFirst (in /afs/cats.ucsc.edu/users/m/rho5/private/cmps101/program2/store)
==498==    by 0x400AA1: main (in /afs/cats.ucsc.edu/users/m/rho5/private/cmps101/program2/store)
==498==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==498==
==498==
==498== Process terminating with default action of signal 11 (SIGSEGV)
==498==  Access not within mapped region at address 0x0
==498==    at 0x400D41: getFirst (in /afs/cats.ucsc.edu/users/m/rho5/private/cmps101/program2/store)
==498==    by 0x400AA1: main (in /afs/cats.ucsc.edu/users/m/rho5/private/cmps101/program2/store)
==498==  If you believe this happened as a result of a stack
==498==  overflow in your program's main thread (unlikely but
==498==  possible), you can try to increase the size of the
==498==  main thread stack using the --main-stacksize= flag.
==498==  The main thread stack size used in this run was 10485760.
==498==
==498== HEAP SUMMARY:
==498==     in use at exit: 952 bytes in 17 blocks
==498==   total heap usage: 39 allocs, 22 frees, 1,480 bytes allocated
==498==
==498== 24 bytes in 1 blocks are still reachable in loss record 1 of 4
==498==    at 0x4A06A2E: malloc (in /opt/rh/devtoolset-2/root/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==498==    by 0x400B81: newList (in /afs/cats.ucsc.edu/users/m/rho5/private/cmps101/program2/store)
==498==    by 0x400958: main (in /afs/cats.ucsc.edu/users/m/rho5/private/cmps101/program2/store)
==498==
==498== 120 bytes in 5 blocks are still reachable in loss record 2 of 4
==498==    at 0x4A06A2E: malloc (in /opt/rh/devtoolset-2/root/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==498==    by 0x400B81: newList (in /afs/cats.ucsc.edu/users/m/rho5/private/cmps101/program2/store)
==498==    by 0x400A34: main (in /afs/cats.ucsc.edu/users/m/rho5/private/cmps101/program2/store)
==498==
==498== 240 bytes in 10 blocks are still reachable in loss record 3 of 4
==498==    at 0x4A06A2E: malloc (in /opt/rh/devtoolset-2/root/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==498==    by 0x400C0C: newNode (in /afs/cats.ucsc.edu/users/m/rho5/private/cmps101/program2/store)
==498==    by 0x40111C: insertOrder (in /afs/cats.ucsc.edu/users/m/rho5/private/cmps101/program2/store)
==498==    by 0x400B02: main (in /afs/cats.ucsc.edu/users/m/rho5/private/cmps101/program2/store)
==498==
==498== 568 bytes in 1 blocks are still reachable in loss record 4 of 4
==498==    at 0x4A06A2E: malloc (in /opt/rh/devtoolset-2/root/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==498==    by 0x35CF8671CA: __fopen_internal (iofopen.c:76)
==498==    by 0x4008E8: openFile (in /afs/cats.ucsc.edu/users/m/rho5/private/cmps101/program2/store)
==498==    by 0x40094A: main (in /afs/cats.ucsc.edu/users/m/rho5/private/cmps101/program2/store)
==498==
==498== LEAK SUMMARY:
==498==    definitely lost: 0 bytes in 0 blocks
==498==    indirectly lost: 0 bytes in 0 blocks
==498==      possibly lost: 0 bytes in 0 blocks
==498==    still reachable: 952 bytes in 17 blocks
==498==         suppressed: 0 bytes in 0 blocks
==498==
==498== For counts of detected and suppressed errors, rerun with: -v
==498== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)
make: *** [valgrind] Segmentation fault (core dumped)

编辑:我相信当列表中只剩下一个元素时尝试删除第一个元素时会出现问题。

【问题讨论】:

  • 它到底是在哪里崩溃的?此外,这并不是所有代码 - 问题很可能出在您未显示的功能之一中。见sscce.org
  • 你的 ListHndl 是指针?它是如何传递给 insertOrder 的?您能否通过编写打印功能来验证至少 2 -3 次插入是否正确?问题/代码非常抽象,所以很难猜测问题在于上面的代码。
  • @fayyazkl,对不起。代码已更新。

标签: c linked-list segmentation-fault doubly-linked-list


【解决方案1】:

当您删除包含至少 2 个元素的列表的第一个元素时,您会删除 else 分支中列表的第一个元素:

L->first->next->prev = NULL;

之后,您在指令中引用NULLed 指针

L->first = L->first->next;

相反,你应该写

L->first = tmp->next;

注意: 此分析假设在您的链表实现中,x-&gt;next-&gt;prev == x

【讨论】:

  • 我按照你的建议更新了,还是一样的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-18
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 2014-08-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多