-1

my problem is it's Process returned -1073741819. What shall i do to compile it faster?

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

Queue::Queue()
{
   topPtr = NULL;
   tailPtr = NULL;
}

bool Queue::isEmpty()
{
  if(topPtr == NULL && tailPtr == NULL)
    return true;
  else
    return false;
}   

void Queue::enqueue(int data)
{
    Node *newNodePtr = new Node;
    newNodePtr->data = data;

    if(topPtr == NULL)
    {
        topPtr = tailPtr = newNodePtr;
        tailPtr->nextPtr = NULL;
    }
    else
    {
        tailPtr->nextPtr = newNodePtr;
        tailPtr = newNodePtr;
        tailPtr->nextPtr = NULL;
    }
}

int Queue::dequeue()
{
    if (isEmpty())
    {
        cout << "empty" <<endl;
    }
    else
    {
        int dataToReturn = topPtr->data;
        Node *nodeToDeletePtr = topPtr;
        dataToReturn = nodeToDeletePtr->nextPtr;
        topPtr = topPtr->nextPtr;
        delete nodeToDeletePtr;

        return dataToReturn;  
    }
}
#ifndef QUEUE_H
#define QUEUE_H

struct Node
{
    int data;
    Node *nextPtr;
};

class Queue
{
public:
    Queue();

    void enqueue(int data);
    int dequeue();
    bool isEmpty();

private:
    Node *topPtr;
    Node *tailPtr;
};

#endif
#include <iostream>
#include <string.h>
#include <cstdlib>
#include "Queue.h"

using namespace std;

int main(int argc, char const *argv[])
{
    Queue integers;
    string seriesIntegers;

    cout << "Enter integers: ";
    getline(cin, seriesIntegers);
    char *seriesIntegersCStr = new char[seriesIntegers.length() + 1];
    strcpy(seriesIntegersCStr, seriesIntegers.c_str());
    char *tokens = strtok(seriesIntegersCStr, " ");

    while(tokens != NULL)
    {
        integers.enqueue(atoi(tokens));
        tokens = strtok(NULL, " ");
    }

    while(!integers.isEmpty())
    {
        cout << " " << integers.dequeue() << "\n";
    }
}
Mat
  • 202,337
  • 40
  • 393
  • 406
gyyy
  • 1
  • 2
    Is that a program termination due to segmentation fault? What do you mean by compile it faster? – dyz May 06 '19 at 10:37
  • 2
    Copy the number into the Windows 7 calculator (Programmer mode, Dword) and switch to Hex. You get `C0000005`. Now, [google "windows C0000005"](https://www.google.com/search?q=windows+C0000005) and you find that's the return code for an Access Violation (MS's term for "Segmentation fault"). ([SO: Exception Error c0000005 in VC++](https://stackoverflow.com/questions/17168982/exception-error-c0000005-in-vc)) – Scheff's Cat May 06 '19 at 10:39
  • 1
    Fyi, `dataToReturn = nodeToDeletePtr->nextPtr;` makes no sense whatsoever. The left side is an `int`, the right is a pointer. And nowhere do you reset `tailPtr` to null when you exhaust the queue. Finally, you neglect any return value (which you promised you would provide) in the case of invoking `dequeue` on an empty queue. There's a reason the standard library returns `void` on its `pop` method of the queue adapter. You can't return something from nothing. – WhozCraig May 06 '19 at 10:45

1 Answers1

2

Among the things wrong:

  • You never reset tailPtr to null during a dequeue operation that emptied the queue.
  • Due to the first item, your isEmpty member was incorrectly reporting the queue still had data because one of the two conditions (tailPtr == nullptr) was not true, and therefore the queue wasn't "empty" even though it was.
  • Due to both of the items above, your while-loop in main ran off the end of the queue.
  • Your dequeue operation has a major control path that returns no value, though you promised in your declaration of returns-int that it would. At a minimum this should throw an exception; ideally it should not be allowed in the first place.
  • Queue should self-clean on destruction rather than leaking the node chain in a non-empty state.
  • As a course of adding a custom destructor to clean dynamic content, Queue should be rule-of-three compliant by either defining proper operations for copy-ctor and assignment operators, or specifying them as deleted (as I did below)

Fixing all of that, and a few other modifications, including entering the real world of modern C++ to utilize a string stream to read the integers rather than strtok and leaked memory as you were before, see the code below:

#include <iostream>
#include <sstream>
#include <string>

struct Node
{
    int data;
    Node *nextPtr;

    Node(int val, Node *next = nullptr)
        : data(val)
        , nextPtr(next)
    {
    }
};

class Queue
{
public:
    Queue();
    virtual ~Queue();

    Queue(const Queue&) = delete;
    Queue& operator =(const Queue&) = delete;

    void enqueue(int data);
    int dequeue();
    bool isEmpty() const;

private:
    Node *topPtr;
    Node *tailPtr;
};

Queue::Queue()
    : topPtr(nullptr)
    , tailPtr(nullptr)
{
}

Queue::~Queue()
{
    while (topPtr)
        dequeue();
}

bool Queue::isEmpty() const
{
    return topPtr == nullptr;
}

void Queue::enqueue(int data)
{
    Node *newNodePtr = new Node(data);

    if (topPtr == NULL)
    {
        topPtr = newNodePtr;
    }
    else
    {
        tailPtr->nextPtr = newNodePtr;
    }
    tailPtr = newNodePtr;
}

int Queue::dequeue()
{
    if (isEmpty())
    {
        throw std::runtime_error("'dequeue' called on an already-empty queue");
    }

    // get top data
    int dataToReturn = topPtr->data;

    // advance top, retaining pointer to old node
    Node *tmp = topPtr;
    topPtr = topPtr->nextPtr;

    // now delete the node
    delete tmp;

    // and reset tail if top hit end-of-queue
    if (topPtr == nullptr)
        tailPtr = nullptr;

    // finally, return data
    return dataToReturn;
}

int main()
{
    std::cout << "Enter integers: ";
    std::string line;
    if (getline(std::cin, line) && !line.empty())
    {
        Queue integers;
        std::istringstream iss(line);
        int value;
        while (iss >> value)
            integers.enqueue(value);

        while (!integers.isEmpty())
            std::cout << integers.dequeue() << '\n';
    }
}

Input

1 2 3 4 5

Output

Enter integers: 1 2 3 4 5
1
2
3
4
5
WhozCraig
  • 65,258
  • 11
  • 75
  • 141