| | |
Linked list implementation of a queue help
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
•
•
Join Date: Sep 2008
Posts: 31
Reputation:
Solved Threads: 0
When I try to compile and run this file I get a segmentation fault when the size function is called so I must not have it set up right.
The size function returns the number of stored chars in the queue.
So I am thinking that the size function in my implementation file is not set up correctly.
Keep in mind that I am not finished I am having some other erors as well but when I get this one resolved I will start working on those.
Header file provided by instructor
my implementation file
The size function starts on line 58.
my test driver
this is my output to the terminal window
At that segmentation fault is where the size function is supposed to print out the number of stored chars. Can someone tell me what I am doing wrong?
The size function returns the number of stored chars in the queue.
So I am thinking that the size function in my implementation file is not set up correctly.
Keep in mind that I am not finished I am having some other erors as well but when I get this one resolved I will start working on those.
Header file provided by instructor
c++ Syntax (Toggle Plain Text)
#ifndef TEMPLATEQ_H #define TEMPLATEQ_H #include <iostream> #include <new> #include <cstddef> using namespace std; class FullTemplateQ // Exception class {}; class EmptyTemplateQ // Exception class {}; template<class SomeType> // Node template class struct QueueNode { SomeType data; // Data stored in queue node QueueNode<SomeType>* nextPtr; // Pointer to next queue node }; template<class SomeType> // Circular queue template class class TemplateQ { private: QueueNode<SomeType>* rearPtr; // Pointer to rear of queue QueueNode<SomeType>* frontPtr; // Pointer to front of queue void PrintNext(QueueNode<SomeType>* tempPtr) const; // Print trailing items public: TemplateQ(); // Default constructor ~TemplateQ(); // Destructor deallocates every node void Enqueue(SomeType newData); // Adds newdata node to rear of queue SomeType Dequeue(); // Removes data node from front of queue, // returning the stored data bool IsFull() const; // Returns true if queue is full, // false otherwise bool IsEmpty() const; // Returns true if queue is empty, // false otherwise int Size() const; // Returns the number of items in queue void ForwardPrint() const; // Prints queue, front to rear void ReversePrint() const; // Prints queue, rear to front }; #include "templateq.cpp" // Very Important!! Do not delete!! #endif
my implementation file
The size function starts on line 58.
c++ Syntax (Toggle Plain Text)
#include <new> #include <cstddef> #include <iostream> //There is no need for #include "templateq.h" since the header file has #include "templateq.cpp" at the end of it. using namespace std; template<class SomeType> TemplateQ<SomeType>::TemplateQ() { frontPtr = NULL; rearPtr = NULL; } template<class SomeType> void TemplateQ<SomeType>::Enqueue(SomeType newData) { if (IsFull()) throw FullTemplateQ(); else if(IsEmpty()) { QueueNode<SomeType>* nextQueueLocation; nextQueueLocation = new QueueNode<SomeType>; nextQueueLocation->data = newData; nextQueueLocation->nextPtr = NULL; if(rearPtr == NULL) frontPtr = nextQueueLocation; else rearPtr->nextPtr = nextQueueLocation; rearPtr = nextQueueLocation; } } template<class SomeType> bool TemplateQ<SomeType>::IsFull()const { QueueNode<SomeType>* tempPtr; try { tempPtr = new QueueNode<SomeType>; delete tempPtr; return false; } catch (std::bad_alloc) { return true; } } template<class SomeType> bool TemplateQ<SomeType>::IsEmpty()const { return (frontPtr == NULL); } template<class SomeType> int TemplateQ<SomeType>::Size() const { int numberOfChars = 0; QueueNode<SomeType>* countPtr; if(IsEmpty()) return 0; while(countPtr != frontPtr) { countPtr = rearPtr->nextPtr; countPtr = countPtr->nextPtr; numberOfChars ++; } return numberOfChars; } template<class SomeType> void TemplateQ<SomeType>::ForwardPrint()const { QueueNode<SomeType>* countPtr; if(IsEmpty()) throw EmptyTemplateQ(); else { countPtr = frontPtr; while(countPtr != rearPtr) { countPtr = countPtr->data; cout << countPtr->data << " "; countPtr = countPtr->nextPtr; } cout << endl; } } template<class SomeType> void TemplateQ<SomeType>::ReversePrint()const {} template<class SomeType> SomeType TemplateQ<SomeType>::Dequeue() { QueueNode<SomeType>* dequeuePtr; if(IsEmpty()) throw EmptyTemplateQ(); else { dequeuePtr = frontPtr; //dequeuePtr = frontPtr->data; frontPtr = frontPtr->nextPtr; if(frontPtr == NULL) rearPtr = NULL; } return dequeuePtr->data; delete dequeuePtr; } template<class SomeType> TemplateQ<SomeType>::~TemplateQ() { QueueNode<SomeType>* tempPtr; while (frontPtr != NULL) { tempPtr = frontPtr; frontPtr = frontPtr->nextPtr; delete tempPtr; } rearPtr = NULL; }
my test driver
c++ Syntax (Toggle Plain Text)
#include "templateq.h" #include <iostream> #include <iomanip> #include <fstream> #include <string> #include <cmath> #include <cstddef> #include <new> int main(int argc, char * const argv[]) { char command, letter; TemplateQ<char> queue; ifstream inputs; if (argc !=2) { cout << "Usage:\n program06 <inputfile>\n"; return 1; } inputs.open(argv[1]); if(!inputs) { cout << "Unable to open file" << endl; return 1; } inputs >> command; if(command != 'c') { cout << "Invalid File Format - missing 'c'\nTerminating program now..." << endl; return 1; } while(!inputs.eof()) { switch(command) { case 'c': { cout << "Constructor()" << endl; break; } case '+': { try { inputs >> letter; //cout << letter << endl; cout << "Enqueue('"; queue.Enqueue(letter); cout << letter << "')"<< endl; } catch(FullTemplateQ) { cout << "Failed Full Queue" << endl; } break; } case '-': { try { cout << "Dequeue() -- "; queue.Dequeue(); cout << queue.Dequeue() << endl; } catch(EmptyTemplateQ) { cout << "Failed Empty Queue" << endl; } break; } case 'p': { cout << "case p" << endl; break; } case 'r': { cout << "case r" << endl; break; } case 's': { cout << "Size () -- " << queue.Size() << endl; break; } case 'd': { queue.~TemplateQ(); cout << "Destructor ()" << endl; break; } default: { cout << "Command not recognized" << endl; } } inputs >> command; } return 0; }
C++ Syntax (Toggle Plain Text)
-bash-3.2$ ./program06 p06input1.txt Constructor() Size () -- 0 Enqueue('a') Enqueue('b') Enqueue('c') Enqueue('d') Enqueue('e') Enqueue('f') case p case r Segmentation fault
At that segmentation fault is where the size function is supposed to print out the number of stored chars. Can someone tell me what I am doing wrong?
c++ Syntax (Toggle Plain Text)
template<class SomeType> void TemplateQ<SomeType>::Enqueue(SomeType newData) { if (IsFull()) throw FullTemplateQ(); else if(IsEmpty()) { QueueNode<SomeType>* nextQueueLocation; nextQueueLocation = new QueueNode<SomeType>; nextQueueLocation->data = newData; nextQueueLocation->nextPtr = NULL; if(rearPtr == NULL) frontPtr = nextQueueLocation; else rearPtr->nextPtr = nextQueueLocation; rearPtr = nextQueueLocation; } }
I'm not quite sure how you want your implementation of a queue to work but...
You only Enque if the list is either empty or full, so after the first Enque the list is no longer empty and unless you're working in a very small heap, or some exception occurs, the IsFull method will return false, so successive calls to Enque will simply do nothing.
One value is stored in your queue and when you call Size I suppose the segmentation fault is caused because you're attempting to indirectly call rearPtr->next when rearPtr points to NULL and the address that its pointing to doesn't belong to your program so an exception occurs and it shuts down.
You need to add another case in your Enque so that when you call it, it can add an element even if its not empty or not full.
Also it might help to code more defensively to prevent a segmentation fault from occurring.
Edit: This statement is confusing--
c++ Syntax (Toggle Plain Text)
while(countPtr != frontPtr) { countPtr = rearPtr->nextPtr; // why is this needed if you're going to reassign countPtr? countPtr = countPtr->nextPtr; numberOfChars ++; } return numberOfChars;
Last edited by Alex Edwards; Oct 23rd, 2008 at 1:00 am.
•
•
Join Date: Sep 2008
Posts: 31
Reputation:
Solved Threads: 0
•
•
•
•
c++ Syntax (Toggle Plain Text)
template<class SomeType> void TemplateQ<SomeType>::Enqueue(SomeType newData) { if (IsFull()) throw FullTemplateQ(); else if(IsEmpty()) { QueueNode<SomeType>* nextQueueLocation; nextQueueLocation = new QueueNode<SomeType>; nextQueueLocation->data = newData; nextQueueLocation->nextPtr = NULL; if(rearPtr == NULL) frontPtr = nextQueueLocation; else rearPtr->nextPtr = nextQueueLocation; rearPtr = nextQueueLocation; } }
Edit: This statement is confusing--
c++ Syntax (Toggle Plain Text)
while(countPtr != frontPtr) { countPtr = rearPtr->nextPtr; // why is this needed if you're going to reassign countPtr? countPtr = countPtr->nextPtr; numberOfChars ++; } return numberOfChars;
c++ Syntax (Toggle Plain Text)
template<class SomeType> void TemplateQ<SomeType>::Enqueue(SomeType newData) { if (IsFull()) throw FullTemplateQ(); else { QueueNode<SomeType>* nextQueueLocation; nextQueueLocation = new QueueNode<SomeType>; nextQueueLocation->data = newData; nextQueueLocation->nextPtr = NULL; if(rearPtr == NULL) frontPtr = nextQueueLocation; else rearPtr->nextPtr = nextQueueLocation; rearPtr = nextQueueLocation; } }
The other part I was trying to walk through the list counting each node as I went.
I tried to comment out that line of code but compile it and run it but I get the same error.
What am I doing wrong?
Last edited by JustLearning; Oct 23rd, 2008 at 2:06 am.
I ran the program (unchanged from the original) in MS Visual C++ 2008 and I got a run-time error where countPtr is being used when it hasn't been initialized.
Try initializing it to null and see if that removes your run-time warning. I'll keep investigating with debug on to see what else I can sift out.
Edit: Ok now I see why you are assigning countPtr to be rearPtr then assigning countPtr to be countPtr->nextPtr
It's because you want to give countPtr a valid address before calling countPtr->rearPtr.
Try initializing it to null and see if that removes your run-time warning. I'll keep investigating with debug on to see what else I can sift out.
Edit: Ok now I see why you are assigning countPtr to be rearPtr then assigning countPtr to be countPtr->nextPtr
It's because you want to give countPtr a valid address before calling countPtr->rearPtr.
Last edited by Alex Edwards; Oct 23rd, 2008 at 2:45 am.
Ok, I got the Size function working.
I changed the code a bit, after reading through your logic some.
The problem was in Size, where you attempted to initialize countPtr to be the rear and compare it to the front.
You're traversing from the low end of the list and further towards lower parts without ascending upwards, so the loop is infinite and will never reach frontPtr.
Here are the changes I made--
The file I used ("C:/MyFile.txt")--
Instead of initializing countPtr in size to point to rear, I made it point to the front and simply traverse down the queue.
I changed the code a bit, after reading through your logic some.
The problem was in Size, where you attempted to initialize countPtr to be the rear and compare it to the front.
You're traversing from the low end of the list and further towards lower parts without ascending upwards, so the loop is infinite and will never reach frontPtr.
Here are the changes I made--
c++ Syntax (Toggle Plain Text)
#ifndef TEMPLATEQ_H #define TEMPLATEQ_H #include <iostream> #include <new> #include <cstddef> using namespace std; class FullTemplateQ // Exception class {}; class EmptyTemplateQ // Exception class {}; template<class SomeType> // Node template class struct QueueNode { SomeType data; // Data stored in queue node QueueNode<SomeType>* nextPtr; // Pointer to next queue node }; template<class SomeType> // Circular queue template class class TemplateQ { private: QueueNode<SomeType>* rearPtr; // Pointer to rear of queue QueueNode<SomeType>* frontPtr; // Pointer to front of queue void PrintNext(QueueNode<SomeType>* tempPtr) const; // Print trailing items public: TemplateQ(); // Default constructor ~TemplateQ(); // Destructor deallocates every node void Enqueue(SomeType newData); // Adds newdata node to rear of queue SomeType Dequeue(); // Removes data node from front of queue, // returning the stored data bool IsFull() const; // Returns true if queue is full, // false otherwise bool IsEmpty() const; // Returns true if queue is empty, // false otherwise int Size() const; // Returns the number of items in queue void ForwardPrint() const; // Prints queue, front to rear void ReversePrint() const; // Prints queue, rear to front }; #include "templateq.cpp" // Very Important!! Do not delete!! #endif
c++ Syntax (Toggle Plain Text)
#ifdef TEMPLATEQ_H #include <new> #include <cstddef> #include <iostream> //There is no need for #include "templateq.h" since the header file has #include "templateq.cpp" at the end of it. using namespace std; template<class SomeType> TemplateQ<SomeType>::TemplateQ() { frontPtr = NULL; rearPtr = NULL; } template<class SomeType> void TemplateQ<SomeType>::Enqueue(SomeType newData) { if (IsFull()) throw FullTemplateQ(); else { QueueNode<SomeType>* nextQueueLocation = NULL; nextQueueLocation = new QueueNode<SomeType>; nextQueueLocation->data = newData; nextQueueLocation->nextPtr = NULL; if(rearPtr == NULL) frontPtr = nextQueueLocation; else rearPtr->nextPtr = nextQueueLocation; rearPtr = nextQueueLocation; } } template<class SomeType> bool TemplateQ<SomeType>::IsFull()const { QueueNode<SomeType>* tempPtr = NULL; try { tempPtr = new QueueNode<SomeType>; delete tempPtr; return false; } catch (std::bad_alloc) { return true; } } template<class SomeType> bool TemplateQ<SomeType>::IsEmpty()const { return (frontPtr == NULL); } template<class SomeType> int TemplateQ<SomeType>::Size() const { int numberOfChars = 0; QueueNode<SomeType>* countPtr = frontPtr; if(IsEmpty()) return 0; while(countPtr != NULL) { //countPtr = rearPtr->nextPtr; countPtr = countPtr->nextPtr; numberOfChars ++; } return numberOfChars; } template<class SomeType> void TemplateQ<SomeType>::ForwardPrint()const { QueueNode<SomeType>* countPtr = NULL; if(IsEmpty()) throw EmptyTemplateQ(); else { countPtr = frontPtr; while(countPtr != rearPtr) { countPtr = countPtr->data; cout << countPtr->data << " "; countPtr = countPtr->nextPtr; } cout << endl; } } template<class SomeType> void TemplateQ<SomeType>::ReversePrint()const {} template<class SomeType> SomeType TemplateQ<SomeType>::Dequeue() { QueueNode<SomeType>* dequeuePtr = NULL; if(IsEmpty()) throw EmptyTemplateQ(); else { dequeuePtr = frontPtr; //dequeuePtr = frontPtr->data; frontPtr = frontPtr->nextPtr; if(frontPtr == NULL) rearPtr = NULL; } return dequeuePtr->data; delete dequeuePtr; } template<class SomeType> TemplateQ<SomeType>::~TemplateQ() { QueueNode<SomeType>* tempPtr = NULL; while (frontPtr != NULL) { tempPtr = frontPtr; frontPtr = frontPtr->nextPtr; delete tempPtr; } rearPtr = NULL; } #endif
c++ Syntax (Toggle Plain Text)
#include "templateq.h" #include <iostream> #include <iomanip> #include <fstream> #include <string> #include <cmath> #include <cstddef> #include <new> int main(int argc, char * const argv[]) { char command, letter; TemplateQ<char> queue; ifstream inputs; //if (argc !=2) //{ cout << "Usage:\n program06 <inputfile>\n"; // return 1; //} //inputs.open(argv[1]); inputs.open("C:/MyFile.txt"); if(!inputs) { cout << "Unable to open file" << endl; return 1; } inputs >> command; // if(command != 'c') // { // cout << "Invalid File Format - missing 'c'\nTerminating program now..." << endl; // return 1; // } while(!inputs.eof()) { switch(command) { case 'c': { cout << "Constructor()" << endl; break; } case '+': { try { inputs >> letter; //cout << letter << endl; cout << "Enqueue('"; queue.Enqueue(letter); cout << letter << "')"<< endl; } catch(FullTemplateQ) { cout << "Failed Full Queue" << endl; } break; } case '-': { try { cout << "Dequeue() -- "; queue.Dequeue(); cout << queue.Dequeue() << endl; } catch(EmptyTemplateQ) { cout << "Failed Empty Queue" << endl; } break; } case 'p': { cout << "case p" << endl; break; } case 'r': { cout << "case r" << endl; break; } case 's': { cout << "Size () -- " << queue.Size() << endl; break; } case 'd': { queue.~TemplateQ(); cout << "Destructor ()" << endl; break; } default: { cout << "Command not recognized" << endl; } } inputs >> command; } cin.ignore(); cin.get(); return 0; }
The file I used ("C:/MyFile.txt")--
c s + a + b + c + d + e + f p r s
Instead of initializing countPtr in size to point to rear, I made it point to the front and simply traverse down the queue.
Last edited by Alex Edwards; Oct 23rd, 2008 at 3:11 am.
![]() |
Similar Threads
- Print function in a queue (C++)
- In desperate need of help with iterative insert method for avl tree. please help (Java)
- qustion about the double link list (C)
- can ANYONE help? need to make a queue (C)
- Program on Queue (C++)
Other Threads in the C++ Forum
- Previous Thread: priority_queue help
- Next Thread: c++ and winapi how to display text using directx
| Thread Tools | Search this Thread |
api array arrays beginner binary bitmap c++ c/c++ calculator char class classes code compile compiler console conversion convert count data database delete desktop developer directshow dll download dynamic encryption error file forms fstream function functions game generator getline givemetehcodez google graph gui homeworkhelper iamthwee ifstream input int integer java lib linkedlist linker linux loop looping loops map math matrix memory multiple news node number output parameter pointer problem program programming project proxy python random read recursion recursive return string strings struct temperature template templates test text text-file tree unix url variable vector video visualstudio win32 windows winsock word wordfrequency wxwidgets





