Fixed C ++ exception. 0xC0000005: Access violation location 0xccccccd0

I've been trying to work this out after a couple of hours by going through my call stack and still haven't figured out what's going on!

My Sequence Database, which basically gathers the information it needs from a file, then calls my Linked List class to create a new node with the collected information, and puts the node at the end of the Linked List:

Title:

#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

      

Source:

#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);
    }


}

      

My linked list header file:

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

      

My source file of the Linked List class:

#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;

}

      

Now I'm new to using classes to contain my linked lists, so I'm not sure if my node structure should be in public or private memory for my Linked List class, or if my constructors are defined the way they should be. A node structure is basically a pointer to the actual data that is in the DNA header file with additional structure pointers for my next and previous nodes so that the data is never mixed, but simply pointed.

The error gets stuck on a line right in the middle of my push_back function in the original Linked List file. I labeled it accordingly. Please, can anyone please elaborate on what I am doing wrong here? Thank!

My main file:

#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;
}

      

+3


source to share


1 answer


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

      

object

is a locally scoped object, which means it is destroyed in the ending parenthesis of the block. You set item

to point to this local object and dispatch if the constructor is disabled DNAList

. The problem is that if you try to access object

after destroying it, your program will no longer be in a valid state. This is because once your object is destroyed, the object that pointed to it will be left as a dangling pointer. Things like dangling pointer access are known as Undefined Behavior.

But that's not where your UB comes from (yet). The real problem is with your constructor DNAList

:

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

      

head

- uninitialized pointer. Primitive objects (e.g., int

, char

, char*

) that are declared but not defined, will not be initialized, and therefore have a null value. Testing objects in this state as if they matter is also Undefined Behavior.



Please note that UB can still get your code to work correctly. But it can also do other nasty things that don't make logical sense in your program.

head

matters what was stored on the stack at the time, which was probably not 0. Thus, the condition fails and is called push_back()

.

Then you execute cur->next

inside a while loop that splits the uninitialized pointer, eventually throwing an exception.

This particular runtime error could have been avoided by setting head

in NULL

inside the constructor body DNAList

and dynamically allocating object

(so that it exists outside the scope of the statement if

, but there are still a few more things out there that don't fit your program, as pointed out in the comments.

+4


source







All Articles