2013-02-15 3 views
0

Почему это вызывает ошибку SegFault? Я попытался запустить backtrace с помощью gdb, но мне это не помогло. Любая помощь будет оценена по достоинству, я вытягивал свои волосы за это часами.Связанный список Ошибка сегментации

мой node.h

#ifndef NODE_H 
#define NODE_H 

#include <string> 
using namespace std; 

class Node 
{ 
    public: 

    Node(const string, const int) ; 
    ~Node() { } 
    void setNext(Node *);//setter for the next variable 
    Node * getNext();// getter for the next variable 
    string getKey();// getter for the key variable 
    int getDistance(); // getter for the dist variable 

    private: 
    Node *next; 
    int dist; 
    string key; 
}; 

#endif 

Мои node.cpp

#include "node.h" 
#include <string> 

Node::Node(string k, int d){ 
    key = k; 
    dist = d; 
} 

void Node::setNext(Node * n){ 
    next = n; 
} 

Node * Node::getNext(){ 
    return next; 
} 

string Node::getKey(){ 
return key; 
} 

int Node::getDistance(){ 
    return dist; 
} 

Мой list.h

#ifndef LIST_H 
#define LIST_H 

#include "node.h" 

class SLL 
{ 
    public: 
     SLL(); 
     ~SLL() { } 
       void Insert (string searchKey, int distance); 
       bool Delete (string searchKey); 
       void Print(); 
       int Search(string searchKey); 

    private: 
     int count; 
     Node *head; 
    Node *iterator; 
    Node *temp; 
}; 

#endif 

мой List.cpp

#include "list.h" 
#include <iostream> 

SLL::SLL():head(0){} 

void SLL::Insert(string searchKey, int distance){ 
Node * temp = new Node(searchKey, distance); 

if(head == 0){ 
    head = temp; 
} 
else{ 
    temp->setNext(head); 
    head = temp; 
} 
} 

bool SLL::Delete(string searchKey){ 
if(head == 0){ 
cout << "An attempt was made to delete a node from an empty list" << endl; 
} 
else{ 
Node* iterator = head; 
Node* last = 0; 

while(iterator != 0){ 
    if (iterator->getKey() == searchKey){ 
    break; 
    } 
    else{ 
    last = iterator; 
    iterator = iterator->getNext(); 
    } 
} 
if (iterator == 0){ 
    return false; 
} 
else{ 
    if(head == iterator){ 
     head = head->getNext(); 

    } 
    else { 
     last->setNext(iterator->getNext()); 
    } 
    delete iterator; 



    } 

    } 
} 

void SLL:: Print(){ 
iterator = head; 
while(iterator != 0){ 
    cout << iterator->getKey() << "-" << iterator->getDistance() << endl; 
    iterator = iterator->getNext(); 
} 

} 

int SLL::Search(string searchKey){ 

} 

Мой main.cpp

#include "list.h" 
#include "node.h" 
#include <iostream> 

using namespace std; 

int main(int argc, char* argv[]) { 
    SLL * sll; 

    sll->Insert("test", 1); 
    sll->Insert("test2", 2); 
    sll->Delete("test"); 
    sll->Print(); 
} 
+2

gdb не предоставил вам никакой помощи ?! Он должен сказать вам, где вы получите segfault, и вы должны сказать нам. – us2012

+1

Как вы думаете, начальное значение sll? – andre

+0

Помимо ошибки, вызвавшей ваш segfault, на который был дан ответ, у вас есть еще несколько проблем: 1. Посмотрите на свой ctor для узла. Вы, кажется, полагаетесь на то, что последний элемент в следующем поле списка равен 0, но устанавливаете ли вы его на 0? 2. Избегайте использования инструкций в ваших файлах заголовков, по крайней мере, в глобальной области. Это гнездо Wasp, ожидающее своего существования (возможно, не в HW-задании, но его хорошая практика держать). См. Http://stackoverflow.com/questions/4872373/why-is-including-using-namespace-into-a-header-file-a-bad-idea-in-c – eladidan

ответ

3

Подсказка: Segfault здесь не происходит: (. Нет полных ответов, как это выглядит как домашнее задание)

int main(int argc, char* argv[]) { 
    SLL * sll; 

    sll->Insert("test", 1); // BIG segfault here. 
    ... 

1

В вашей основной функции, указатель на SSL является не инициализирован, но вы разыгрываете его. Это неопределенное поведение. В вашем конкретном случае это вызывает нарушение сегментации. Попробуйте изменить вам код, чтобы создать SSL объект, либо в стеке:

int main(int argc, char* argv[]) { 
    SLL sll; 

    sll.Insert("test", 1); 
    // ... 
} 

или кучи:

int main(int argc, char* argv[]) { 
    SLL * sll = new SLL(); 

    sll->Insert("test", 1); 
    // ... 
} 

Кстати, вы никогда не используя temp, iterator, ... полей SLL класс, никогда не инициализируйте их. В вашей реализации вы определяете локальные переменные, которые скрывают их, поэтому я предлагаю удалить поля или инициализировать их в конструкторе.

+0

Зачем вообще использовать указатель для объекта -о-стоп-решение ?! – us2012

+0

Вы правы, исправлены, чтобы использовать обозначение '.'. Я просто не хотел слишком сильно менять структуру кода. –

+0

Большое спасибо! Это фиксировало проблему, я не могу поверить, что я это не замечал. – user2073188