简体   繁体   中英

Weird segfault in C++

I am checking data of head node in constructor and its ok, but when i am checking it in the function then its gone. Why is it such a ghost this pointer ?

header for queue

#ifndef QUEUE_H
#define QUEUE_H
#include "Node.h"
#include "LinkedList.h"

class Queue
{
    public:
        Queue();
        ~Queue();
        void addTail(Node* newNode);
        Node* deleteHead();
        int isEmpty();
        void PrintQueue(char* outName);

    protected:
    private:
        Node* head;
        Node* tail;
        LinkedList* myList;
};

#endif // QUEUE_H

queue class

#include "Queue.h"

Queue::Queue()
{
    //constructor
    myList =  new LinkedList();
    head = myList->getHead();
    std::cout<<" head here is " << head->getData()<<std::endl; //
    std::cout<<" next after head is " << head->getNext()->getData()<<std::endl; //
    tail = myList->getTail();
}

void Queue::addTail(Node* newNode)
{
    std::cout<<"inserting before tail (queue)"<<std::endl;
    std::cout<<"new node is " << newNode->getData() <<std::endl;
    std::cout<<" head here is " << myList->getHead()->getData() <<std::endl;
    myList->insertLast(newNode);
}

Node* Queue::deleteHead()
{
    if(isEmpty()){
        std::cout<<"Queue is empty. Cannot remove anything anymore. Add more data to the queue!"<<std::endl;
        return head;
    }
    return myList->removeFirst();
}

int Queue::isEmpty()
{
    return myList->isEmpty();
}

void Queue::PrintQueue(char* outName)
{
    Node* cur = head->getNext(); //store current node to keep track. Set it to one after the head
    std::ofstream outfile;
    outfile.open(outName, std::ios::app);
    outfile << "Printing the values of the queue: ";
    std::cout<<"Printing the values of the queue: "<<std::endl;
    while(cur != tail)
    {
       std::cout<< cur->getData()<<", "<<std::endl; //print to the console
       outfile << cur->getData() <<", "; //print to file
    }
    outfile.close();
}

Queue::~Queue()
{
    //destructor
    delete myList;
}

Main function

#include <iostream>
#include <fstream>
#include <string>
#include "Stack.h"
//#include "Stack.cpp"
#include "LinkedList.h"
//#include "LinkedList.cpp"
#include "Node.h"
//#include "Node.cpp"
#include "HashTable.h"
//#include "HashTable.cpp"


using namespace std;

int main( int argc, char* argv[] )
{
   //specifying the in and out files
    char* inFileName = argv[1];
    char* outFileName = argv[2];


    std::fstream infile (inFileName) ; // input file
    //open the input file and find largest integer
    int num;
    int largest = 0;
    Stack * myStack = new Stack();
    char buffer[33]; //create a buffer for using with itoa
    std::ofstream outfile;
    outfile.open(outFileName);

    if ( !infile.is_open() ) //check if input file is open
      cout<<"Could not open file\n";
    else {
        while (infile >> num) { // read file int by int and check if current is not the largest
            if(num > largest) largest = num;
            Node *newNode= new Node(itoa(num,buffer,10));
            myStack->push(newNode);
        }
    }
    std::cout<< std::endl;
    infile.close(); //close files that you read to avoid memory leaks

    myStack->PrintStack(outFileName);

    HashTable* hashBrown = new HashTable();

    int currentDigit = 0;
    int currentTable = 0;
    int numOfDig =0; //stores number of digits of the largest number
    string maxNum = itoa(largest,buffer,10);
    numOfDig = maxNum.length();
    std::cout<< "Num of digits " << numOfDig << std::endl;
    Node* current;
    while(!myStack->isEmpty())
    {
        current = myStack->pop();
        std::cout<< "pop from stack element " << current->getData() << std::endl;
        string str = current->getData();
        int index = atoi(&str.back());
        std::cout<< "insert at index " << index << std::endl;
        std::cout<< "inserting data: "<< current->getData()<< " at index:" << index << std::endl;
        hashBrown->myQueues[index].addTail(current);

    }
    hashBrown->printHashTable(outFileName);


    delete myStack;
    delete hashBrown;

    outfile.close();
    std::cout<< "finishing program " << std::endl;
    return 0;

}

Linked List

#include "LinkedList.h"
#include "Node.h"




LinkedList::LinkedList()
{
    //constructor
    head = new Node("head"); //dummy variable
    tail = new Node("tail"); //dummy variable
    head->setNext(tail);

}

void LinkedList::insertNode(Node* newNode, Node *position)
{

    newNode->setNext(position->getNext());         // set its pointer to position
    position->setNext(newNode);
}

void LinkedList::insertFirst(Node* newNode)
{
    std::cout<<"head here is  "<< head->getData() <<std::endl; //
    insertNode(newNode, head);
}

void LinkedList::insertLast(Node* newNode)
{
    std::cout<<"inserting before tail (LinkedList)"<<std::endl; //
    Node* cur = head;
    std::cout<<"outside the loop "<< cur->getData() <<std::endl; //
    std::cout<<"current node is "<< cur->getData() <<std::endl; //
    while(cur->getNext() != tail) //iterate until you reach one before tail
    {
        std::cout<<"current node is "<< cur->getData() <<std::endl; //
        cur = cur->getNext();

    }
    std::cout<<"inserting before tail"<<std::endl; //
    insertNode(newNode, cur); //insert at the end before the dummy tail

}

Node* LinkedList::removeFirst()
{
    if(isEmpty())
    {
        return head;
    }
    Node* result = head->getNext(); //store pointer to Node that you need to return
    head->setNext(result->getNext());
    return result;
}


Node* LinkedList::getTail()
{
    return tail;
}

Node* LinkedList::getHead()
{
    return head;
}

int LinkedList::isEmpty()
{
    return head->getNext() == tail;
}

std::string LinkedList::printList(){
    Node *current = head;
    std::string str;
    //append pieces of string to create new line
    while(current != tail){
            str.append (" --> (");
            str.append ( current->getData());
            str.append (",");
            str.append (current->getNext()->getData());
            str.append (")") ;
            current = current->getNext();
    }
    std::cout<<str<<std::endl; //display new
    return str; //return string containing next line that will be written to a file in main

}

LinkedList::~LinkedList()
{
    //destructor
    Node *current = head;
    while( current->getNext() != tail ) { //go through whole linked list and delete each node to free memory
        Node* next = current->getNext();
        delete current;
        current = next;
    }
    delete current;
    delete tail;
}

So everything works fine until it tries to access the head or its data in the addTail() function of Queue.

You can use gdb to debug your program, find the bugs and fix them. If the program cored, you can use backtrace to see what caused the core.

  1. Set breakpoint at the lines you think program behavior wired, you can also let the program run step by step.
  2. Run the program and print variable value to see whether the variable value is expected. If the variable is a pointer, you can also print the content it referenced.

A brief gdb tutorial

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM