2010-11-23 3 views
1

Я пишу программу в качестве задания для школы, и я, хотя я разработал все ошибки до тех пор, пока не решил назвать свой конструктор копий. Программа является интерактивной (CLI), которая в основном имеет два модальных файла: .h и .cpp для класса LList и .h и .cpp для структуры программы, а также 3-й файл cpp только для main(). Предполагается, что это программа для гидроэнергетической компании (фальшивая компания), в которой узлы LList содержат данные для годового потока воды в реке (год и течение). Вот некоторое представление о классе:C++ Связанный список Ошибка сегментации

//list.h 
struct ListItem { 
    int year; 
    double flow; 
}; 

struct Node { 
    ListItem item; 
    Node *next; 
}; 

class FlowList { 
public: 
    FlowList(); 
    // PROMISES: Creates empty list 

    FlowList(const FlowList& source); 
    // REQUIRES: source refers to an existing List object 
    // PROMISES: create the copy of source 

    ~FlowList(); 
    // PROMISES: Destroys an existing list. 

    FlowList& operator =(const FlowList& rhs); 
    // REQUIRES: rhs refers to an existing FlowList object 
    // PROMISES: the left hand side object becomes the copy of rhs 

    //....Other member functions 

private: 
    // always points to the first node in the list. 

    Node *headM; 
    // Initially is set to NULL, but it may point to any node. 

    Node *cursorM; 
    //For node manipulation within interactive CLI 

    void copy(const FlowList& source); 

    void destroy(); 

Я верю утечку памяти или столкновение происходит где-то в пределах функции копирования, но косяк точки контактном где.

//list.cpp 

FlowList::FlowList() : headM(0), cursorM(0) {} 

FlowList::FlowList(const FlowList& source) 
{ 
    copy(source); 
} 

FlowList::~FlowList() 
{ 
    destroy(); 
} 

FlowList& FlowList::operator =(const FlowList& rhs) 
{ 
    if (this != &rhs) 
    { 
    destroy(); 
    copy(rhs); 
    } 
    return (*this); 
} 

//...more function definitions 

void FlowList::copy(const FlowList& source) 
{ 
    if (source.headM == NULL) 
    { 
    headM = NULL; 
    cursorM = NULL; 
    return; 
    } 

    Node* new_node = new Node; 
    assert(new_node); 
    new_node->item.year = source.headM->item.year; 
    new_node->item.flow = source.headM->item.flow; 
    new_node->next = NULL;  
    headM = new_node; 

    Node* thisptr = new_node; 

    for(Node* srcptr = source.headM->next; srcptr != NULL; srcptr = srcptr->next) 
    { 
    new_node = new Node; 
    assert(new_node); 
    new_node->item.year = srcptr->item.year; 
    new_node->item.flow = srcptr->item.flow; 
    new_node->next = NULL; 
    thisptr->next = new_node; 
    thisptr = thisptr->next; 
    } 

} 

void FlowList::destroy() 
{ 
    Node* ptr = headM; 
    Node* post = headM->next; 

    while (ptr != NULL) 
    { 
    delete ptr; 
    ptr = post; 
    if (post) 
     post = ptr->next; 
    } 
    headM = NULL; 
} 

Программа отлично работает, если я создаю объект FlowList, залейте его данными из .dat-файла; Затем я могу манипулировать данными внутри программы (отображать, выполнять вычисления, добавлять в список, удалять из списка и сохранять данные в файл), но сбой программы (segmentation fault), если я создаю другой объект FlowList (в main.cpp). Любая помощь будет действительно оценена.

+0

Почему у вас есть экземпляр-конструктор и деструктор, вызывающие другие функции вместо выполнения там работы? – Falmarri 2010-11-23 00:09:50

+1

В скопировании вы не устанавливаете cursorM, если (source.headM! = NULL) (просто что-то, что меня поразило как нечетное) – Akusete 2010-11-23 00:11:29

ответ

4

Начальная вещь, я заметить, что это выглядит как ваша destroy() функция всегда будет Сегментация ошибку, если список пуст:

void FlowList::destroy() 
{ 
    Node* ptr = headM; 
    Node* post = headM->next; 
    //... 
} 

Если список пуст, headM является NULL, а затем вы пытаетесь do headM->next, который всегда будет производить ошибку сегментации в этом случае.

Возможно, у вас также может быть утечка памяти в вашем конструкторе копирования, если вы пройдете пустой список. Если вы посмотрите на этот код:

void FlowList::copy(const FlowList& source) 
{ 
    if (source.headM == NULL) 
    { 
    headM = NULL; 
    cursorM = NULL; 
    return; 
    } 
    //... 
} 

Что делать, если текущий список содержал 20 пунктов и source является пустым списком? Вы устанавливаете текущий список headM и cursorM на NULL, но вы никогда не вызываете delete на любом из узлов в текущем списке, который вы изначально использовали для создания new. Вероятно, вы захотите также использовать свою функцию destroy() в своем конструкторе копирования (вы сделали это для функции operator=).

Последнее, что я заметил, это то, что вы не инициализируете cursorM для непустого списка в вашей функции copy() (@Akusete также указал на это). Я думаю, что рекомендовал бы в начале вашего конструктора копирования просто инициализировать cursorM и headM до NULL, чтобы покрыть ваши базы.

Похоже, вы действительно близки, я думаю, вам просто нужно подумать о граничном случае с пустыми списками (как на LHS, так и на RHS), и вы, вероятно, найдете большинство этих ошибок. Удачи!

Смежные вопросы