首页 > 解决方案 > 如何修复 C++ 中的“分段错误(核心转储)”?

问题描述

我正在尝试使用类在 C++ 中创建链接列表。我只使用了两种方法,即 pushFront() 和 traverse() 来将新元素推送到链表的头部,并在任何给定时间显示列表中的元素。每当我使用遍历方法时,我都会收到错误“分段错误”

我的代码如下所示。我在这个站点和其他地方查找了这个错误。当我们尝试访问不属于我们的变量时,据说会发生分段错误。即这是我们无法进入的空间。但正如在我的代码中看到的那样,我试图使用 head 和 tail 类的私有成员。但我在类本身的方法中使用它们。所以我应该被允许这样做吗?我不知道我哪里错了。

#include <iostream>
using namespace std;
struct Node
{
    int data;
    Node * next;
};
class LinkedList
{
    private:
        Node * head;
        Node * tail;
    public:
        LinkedList();
        void pushFront(int i);
        void traverse();
};
LinkedList::LinkedList()
{
    Node * head = NULL;
    Node * tail = NULL;
}
void LinkedList::pushFront(int i)
{
    Node * newNode =new Node;
    newNode->data=i;
    newNode->next=head;
    head=newNode;
    if(tail==NULL)
        tail = head;
}
void LinkedList::traverse()
{
    if (head==NULL){
        cout<<"empty list. add elements";
        return;
    }
    Node * ptr =  head;
    while(ptr!=NULL)
    {
        cout<<ptr->data;
        ptr=ptr->next;
    }
}
int main()
{
    LinkedList l;
    l.pushFront(10);
    l.pushFront(9);
    l.traverse();
    return 0;
}

我希望输出应该是910应该通过遍历打印的。但我得到分段错误错误。谁能指出我错在哪里?

标签: c++linked-list

解决方案


LinkedList::LinkedList()
{
  Node * head = NULL;
  Node * tail = NULL;
}

必须是(最小的变化):

LinkedList::LinkedList()
{
  head = NULL;
  tail = NULL;
}

否则你不会初始化正确的属性而是局部变量


我鼓励你编译产生所有的警告,如果我用g++ -Wall -pedantic c.cc这个编译你的代码给

c.cc: In constructor 'LinkedList::LinkedList()':
c.cc:20: warning: unused variable 'head'
c.cc:21: warning: unused variable 'tail'

这正是问题所在


关于valgrind,如果我在它下面执行,则会给出:

valgrind ./a.out
==18508== Memcheck, a memory error detector
==18508== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==18508== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==18508== Command: ./a.out
==18508== 
==18508== Conditional jump or move depends on uninitialised value(s)
==18508==    at 0x400829: LinkedList::pushFront(int) (c.cc:29)
==18508==    by 0x4008C2: main (c.cc:48)
==18508== 
==18508== Conditional jump or move depends on uninitialised value(s)
==18508==    at 0x40089A: LinkedList::traverse() (c.cc:39)
==18508==    by 0x4008DF: main (c.cc:50)
==18508== 
==18508== Use of uninitialised value of size 8
==18508==    at 0x400876: LinkedList::traverse() (c.cc:41)
==18508==    by 0x4008DF: main (c.cc:50)
==18508== 
==18508== Use of uninitialised value of size 8
==18508==    at 0x400888: LinkedList::traverse() (c.cc:42)
==18508==    by 0x4008DF: main (c.cc:50)
==18508== 
==18508== Invalid read of size 4
==18508==    at 0x400876: LinkedList::traverse() (c.cc:41)
==18508==    by 0x4008DF: main (c.cc:50)
==18508==  Address 0x4b43415254475542 is not stack'd, malloc'd or (recently) free'd
==18508== 
==18508== 
==18508== Process terminating with default action of signal 11 (SIGSEGV)
==18508==  General Protection Fault
==18508==    at 0x400876: LinkedList::traverse() (c.cc:41)
==18508==    by 0x4008DF: main (c.cc:50)
9101778121006==18508== 
==18508== HEAP SUMMARY:
==18508==     in use at exit: 32 bytes in 2 blocks
==18508==   total heap usage: 2 allocs, 0 frees, 32 bytes allocated
==18508== 
==18508== LEAK SUMMARY:
==18508==    definitely lost: 0 bytes in 0 blocks
==18508==    indirectly lost: 0 bytes in 0 blocks
==18508==      possibly lost: 0 bytes in 0 blocks
==18508==    still reachable: 32 bytes in 2 blocks
==18508==         suppressed: 0 bytes in 0 blocks
==18508== Rerun with --leak-check=full to see details of leaked memory
==18508== 
==18508== For counts of detected and suppressed errors, rerun with: -v
==18508== Use --track-origins=yes to see where uninitialised values come from
==18508== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 6 from 6)
Segmentation fault

所以你也看到头部尾部没有初始化等


推荐阅读