2014-09-02 5 views
3

Я пытался проделать это через пару часов, пройдя свой стек вызовов, и еще не понял, что происходит!Исключенное исключение C++. 0xC0000005: Место чтения нарушения доступа 0xccccccd0

Моя база данных последовательности, которая в основном собирает информацию, необходимую из файла, а затем вызывает на моем Linked класса List, чтобы создать новый узел с собранной информацией, и поставить этот узел в конце связного списка:

Заголовок:

#ifndef SEQUENCE_H 
#define SEQUENCE_H 
#include "DNA.h" 
#include "DNAList.h" 

class SequenceDatabase 
{ 
public: 
    //Default Constructors 
    SequenceDatabase(); 

    //Methods 
    void importEntries(string); 


private: 
    DNAList list; 
}; 

#endif 

Источник:

#include "SequenceDatabase.h" 
#include "DNA.h" 
#include "DNAList.h" 
#include <fstream> 

using namespace std; 
SequenceDatabase::SequenceDatabase() //Default Constructor. 
{ 
    DNA object; 
    DNAList list; 
} 

void SequenceDatabase::importEntries(string name) 
{ 
    DNA* item; 
    ifstream file; 
    file.open(name); 

    if(!file.is_open()) 
    { 
     cout << "Error opening file!" << endl; 
     exit(1); 
    } 

    char letter; 
    string label, sequence; 
    int ID, length, index; 
    file >> letter; 

    if(letter == 'D' || letter == 'd') 
    { 
     file >> label >> ID >> sequence >> length >> index; 
     DNA object(label,ID,sequence,length,index); 
     item = &object; 
     DNAList list(item); 
    } 


} 

Мой Связанный файл Список заголовков:

class DNAList 
{ 
public: 
    //Constructors 
    DNAList(); 
    DNAList(DNA* newDNA); 

    //Linked List Functions 
    void push_back(DNA* newDNA); 
    DNA* findID(int ID); 
    void obliterate(int ID); 

    //DNANode struct for Linked List 
    struct DNANode 
    { 
     DNA* data; 
     DNANode* next; 
     DNANode* prev; 
    }; 


private: 
    DNANode* head; 
    typedef DNANode * ptr; 
}; 

#endif 

Мой Связанный список источников файл класса:

#include "DNAList.h" 
#include "SequenceDatabase.h" 
#include "DNA.h" 
#include <iostream> 

using namespace std; 

DNAList::DNAList() 
{ 
    head = NULL; 


} 

DNAList::DNAList(DNA* newDNA) 
{ 
    cout <<"In DNA list second constructor" << endl; 
     ptr cur; 
    if(head == NULL) 
    { 
     ptr newNode = new DNANode; 
     cur = newNode; 
     cur -> data= newDNA; 
     head = cur; 
     cur -> prev = head; 
     cur -> next = NULL; 
    } 
    else 
    { 
     push_back(newDNA); 
    } 
} 

void DNAList::push_back(DNA* newDNA) 
{ 
    ptr cur; 
    ptr last; 
    cout << "Note: Adding " << newDNA -> getID() << " ..." << endl; 
    ptr newNode = new DNANode; 
    cur = head; 
    while(cur != NULL) 
    { 
     last = cur; 
     cur = cur -> next; //ERROR IS HAPPENING AT THIS LINE. 
    } 
    newNode -> data = newDNA; 
    newNode -> prev = last; 
    newNode -> next = NULL; 
    cur = newNode; 

} 

Теперь, я новичок в использовании классов, чтобы содержать свои связные списки, поэтому я не уверен, что если мой узел структура должна быть в государственной или частной памяти мой класс Linked List, а также, если мои конструкторы определены так, как они должны быть. Структура узла - это в основном указатель на фактические данные, которые находятся в файле заголовка DNA с дополнительными указателями на структуру для моих следующих и предыдущих узлов, так что данные никогда не смешиваются, а просто указываются.

Ошибка связана с строкой прямо в середине моей функции push_back в исходном файле Linked List. Я обозначил его соответствующим образом. Пожалуйста, кто-нибудь может рассказать о том, что я делаю неправильно здесь? Благодаря!

Мой главный файл:

#include <iostream> 

using namespace std; 

#include "sequenceDatabase.h" 

int main(){ //int argc, char* argv[]){ 
    string commandsFileName; 
    commandsFileName = "lab1-commands-short.tab"; // for initial development 
    //commandsFileName = "lab1-commands.tab"; 
    // commandsFileName = "lab1-commands-test.tab"; // for testing & grading 

    SequenceDatabase entries; 
    cout << "Importing " << commandsFileName << endl; 
    entries.importEntries(commandsFileName); 

    return 0; 
} 
+0

Вы вводите в заблуждение всевозможные вещи. Например, 'DNAList list (item);' ничего не делает для класса 'list'. Он создает локальную переменную , также называемый 'list', который затем сразу же уничтожается в конце области действия. Кроме того, он передает адрес' object' в конструктор 'DNAList', но' object' является локальным, поэтому будет уничтожен в закрывающей скобке о f, которые тоже блокируются, поэтому вы храните висячий указатель. –

+0

Что происходит в вашем конструкторе 'DNAList'? Что это временно в помощь «ptr cur»? Почему вы сохраняете указатель на другой временный объект ('object'), который должен быть уничтожен в' importEntries'? Почему 'importEntries' возвращается без каких-либо действий с' list'? Кажется, что с этим кодом больше ошибочно, чем правильно. – user657267

+1

Кроме того, в стандартной библиотеке есть дважды связанный список: 'std :: list'. Если вы можете, используйте его, а не напишите свой собственный. –

ответ

4
if (...) 
{ 
    DNA object(label, ID, sequence, length, index); 
    item = &object; 
    DNAList list(item); 
} 

object является локально-Scoped объект, то есть он будет уничтожен в конечной скобкой блока. Вы устанавливаете item, чтобы указать на этот локальный объект и отправить, если отключено, до конструктора DNAList. Проблема в том, что если вы попытаетесь получить доступ к object после его уничтожения, ваша программа больше не будет в правильном состоянии. Это связано с тем, что как только ваш объект будет уничтожен, объект, который указал на него, будет оставлен как обвисший указатель. Такие вещи, как доступ к оборванному указателю, называются Undefined Behavior.

Но это не то место, где находится ваш UB (пока). Реальная проблема заключается в вашем DNAList конструктора:

if (head == NULL) 
{ 
    // ... 
} 
else 
{ 
    push_back(newDNA); 
} 

head является неинициализированным указателем. Примитивные объекты (например, int, char, char*), которые объявлены, но не определены, неинициализированы и, следовательно, имеют неопределенное значение. Тестирование объектов в этом состоянии, как будто они имеют значение, также является неопределенным поведением.

Обратите внимание, что UB все еще может работать, чтобы ваш код работал правильно. Но он также может делать другие неприятные вещи, которые не имеют логического смысла в вашей программе.

head имеет значение того, что хранилось в стеке в тот момент, что, вероятно, не было 0.Таким образом, условие не выполняется и вызывается push_back().

Затем вы делаете cur->next внутри цикла while, который разделяет неинициализированный указатель, в результате чего возникает исключение.

Эта конкретная ошибка во время выполнения можно было бы избежать, установив head в NULL внутри конструктора тела DNAList и динамического распределения object (так, что она существует за рамки if заявления, но есть еще несколько вещей, которые не являются прямо в вашей программе, как указано в комментариях.

+0

Спасибо, я чувствую, что теперь я могу лучше понять и попробовать и проработать это. –