Exception thrown: read access violation this->pCurr was 0xDDDDDDDD - c++

I am a beginner and am working on linked list. I am trying to make a method that removes the current link of a list. I am getting an exception : read access violation this->pCurr was 0xDDDDDDDD.
This is what my code looks like (I removed some methods, such as adding links and left only those related to removal)
template <class T>
struct TNode {
T val;
TNode<T> *pNext;
};
template <class T>
class TList {
protected:
TNode <T> *pFirst, *pLast, *pCurr, *pPrev, *pStop;
int len; //lenght
int pos;//where pCurr shows
public:
//constructor
TList() {
pFirst = NULL;
pLast = NULL;
pCurr = NULL;
pPrev = NULL;
pStop = NULL;
len = 0;
pos = 0;
}
//destructor
~TList() {
TNode<T> *tmp = pFirst;
//if (tmp == pStop)
//delete tmp;
while (pFirst != pStop) {
pFirst = pFirst->pNext;
delete tmp;
tmp = pFirst;
}
}
//delete first link
void DelFirst() {
T res = pFirst->val;
TNode<T> *tmp;
tmp = pFirst;
pFirst = pFirst->pNext;
delete tmp;
len--;
}
//delete current link
void DelCurr() {
if (pCurr == pFirst)
DelFirst();
else {
TNode<T> *tmp = pCurr;
pPrev->pNext = pCurr->pNext; // an exception is thrown on this line
pCurr = pCurr->pNext;
delete tmp;
len--;
}
}
//set pCurr to the beginning
void Reset() {
pCurr = pFirst;
pPrev = pStop;
pos = 0;
}
//go to the next link
void GoNext() {
//if (IsEnd()) throw - 1;
//else {
pPrev = pCurr;
pCurr = pCurr->pNext;
pos++;
//}
}
//end check
bool IsEnd() {
return (pCurr == pStop);
}
//delete the whole list
void DelList() {
for (Reset(); !IsEnd(); GoNext()) {
DelCurr();
}
DelCurr();
}
};
Please tell me what this exception is related to and how to fix it.

Check for null pointers everywhere
And in DelFirst() function, set the pCurr to the next, when it points on pFirst
void DelFirst()
{
if (pFirst == NULL)
{
return;
}
if (pCurr == pFirst)
{
pCurr = pFirst->pNext;
}
T res = pFirst->val;
TNode<T>* tmp;
tmp = pFirst;
pFirst = pFirst->pNext;
delete tmp;
len--;
}

Related

Why is there a memory leak in my program?

I have implemented a singly-linked-list where there is a SinglyList class, and struct node, node *head as private members of the class; and wrote a destructor to delete it. I used CRT library to check for memory leaks using _CrtDumpMemoryLeaks() method. When I debug the code, it shows in the debug console that memory leaks are found, which is strange since I wrote a destructor to delete it.
This is shown in the debug console:-
Here is the node class:-
struct node
{
int data = NULL;
node*next = NULL;
};
Here is the destructor:-
SinglyList::~SinglyList()
{
node*curr = head,*next;
while(curr != NULL)
{
next = curr->next;
delete curr;
curr = next;
}
}
I don't understand, how can there be memory leaks when all nodes are deleted, kindly help.
Edit:
SinglyList.hpp:-
#pragma once
#include<iostream>
class SinglyList
{
private:
struct node
{
int data = NULL;
node*next = NULL;
};
node*head;
public:
SinglyList();
void Append(const int&);
void Prepend(const int&);
void Print();
void Insert(const int&,const int&);
void Delete(const int&);
void Reverse();
bool isEmpty();
~SinglyList();
};
SinglyList::SinglyList()
{
head = NULL;
}
SinglyList::~SinglyList()
{
node*curr = head,*next;
while(curr != NULL)
{
next = curr->next;
delete curr;
curr = next;
}
}
void SinglyList::Append(const int&data)
{
node*n = new node{data};
if(!head)
{
head = n;
return;
}
node*ptr = head;
while(ptr->next)
ptr = ptr->next;
ptr->next = n;
}
void SinglyList::Prepend(const int&data)
{
node*n = new node{data};
if(!head)
{
head = n;
return;
}
n->next = head;
head = n;
}
void SinglyList::Print()
{
if(!head)
return;
node*ptr = head;
while(ptr)
{
std::cout<<ptr->data<<' ';
ptr = ptr->next;
}
std::cout<<std::endl;
}
void SinglyList::Insert(const int&pos,const int&data)
{
if(pos == 1)
{
Prepend(data);
return;
}
node*n = new node{data};
node*ptr = head;
for(int i = 1;i!=pos-1;i++)
ptr = ptr->next;
n->next = ptr->next;
ptr->next = n;
}
void SinglyList::Delete(const int&pos)
{
if(!head)
return;
node*ptr = head;
if(pos == 1)
{
head= head->next;
delete ptr;
return;
}
for(int i = 1;i!= pos-1;i++)
ptr = ptr->next;
node*temp = ptr->next;
ptr->next = temp->next;
delete temp;
}
void SinglyList::Reverse()
{
if(!head)
return;
node*curr = head,*prev = NULL,*next = NULL;
while(curr)
{
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
head = prev;
}
bool SinglyList::isEmpty()
{
return (!head);
}
main.cpp:-
#include"SinglyList.hpp"
#include<crtdbg.h>
int main()
{
SinglyList nums{};
nums.Append(10);
nums.Append(20);
nums.Append(30);
_CrtDumpMemoryLeaks();
return 0;
}
You print the leaks before the list gets deleted. Try this instead:
#include"SinglyList.hpp"
#include<crtdbg.h>
int main()
{
{
SinglyList nums{};
nums.Append(10);
nums.Append(20);
nums.Append(30);
}
_CrtDumpMemoryLeaks();
return 0;
}
Then, you'll show the actual leaks after your list gets destroyed.

Doubly Linked List fails to add or delete valid entries

I've run it many times. I tried fixing my deleteNode() and addNode(), but it did not work. The output showed me that it failed to add some valid entries in my list, which resulted in failing to delete these valid entries. Someone please help me find the errors... I think either my isEmpty() is wrong or the addNode got messed up.
// Add nodes and makes it work in any cases: backward/forward
bool LinkedList::addNode(int id, string str) {
bool result = false;
if (id >= 0 && !(idExists(id))) {
Node *current = head;
Node *temp = new Node;
temp->data.data = str;
temp->data.id = id;
temp->forward = NULL;
temp->back = NULL;
// Kinds of adding cases
if(head == NULL) { // Check if list is empty
addHead(temp, current);
result = true;
} else {
while(temp->data.id > current->data.id && current->forward != NULL) {
current = current->forward;
}
// Backward
if(current->back == NULL) {
if(temp->data.id > current->data.id) {
if(current->forward == NULL) {
addTail(temp, current);
} else {
addMiddle(temp, current);
}
} else {
addHead(temp, current);
}
result = true;
// Forward
}else if(current->forward == NULL) {
if (temp->data.id > current->data.id) {
addTail(temp, current);
} else {
addMiddle(temp, current);
}
result = true;
}else {
if(temp->data.id > current->data.id) {
addMiddle(temp, current);
result = true;
}
}
}
}
return result;
}
void LinkedList::addHead(Node *temp, Node *current) {
if (head != NULL){
temp->forward = current;
current->back = temp;
head = temp;
} else {
head = temp;
}
}
void LinkedList::addMiddle(Node *temp, Node *current) {
temp->forward = current;
temp->back = current->back;
current->back->forward = temp;
current->back = temp;
}
void LinkedList::addTail(Node *temp, Node *current) {
current->forward = temp;
temp->back = current;
}
// Delete list
bool LinkedList::deleteNode(int id){
bool result = false;
if (idExists(id)) {
Node *current = head;
while (current->forward != NULL && current->data.id != id) {
current = current->forward;
}
if (current->data.id == id && current->forward == NULL) {
if (current->back == NULL) { // Delete head
delete current;
head = NULL;
} else { // delete tail
deleteTail(current);
}
result = true;
} else if (current->data.id == id) {
if (current->back == NULL)
deleteHead(current);
else // delete middle
deleteMiddle(current);
result = true;
}
}
return result;
}
// Helper delete functions
void LinkedList::deleteHead(Node *current) {
head = current->forward;
head->back = NULL;
delete current;
}
void LinkedList::deleteMiddle(Node *current) {
current->back->forward = current->forward;
current->forward->back = current->back;
delete current;
}
void LinkedList::deleteTail(Node *current) {
current->back->forward = NULL;
delete current;
}
bool LinkedList::getNode(int id, Data *data) {
bool didGetNode = false;
if (idExists(id)) {
Node *current = head;
while (current->forward != NULL && current->data.id != id) {
current = current->forward;
}
data->id = current->data.id;
data->data = current->data.data;
didGetNode = true;
}
return didGetNode;
}
// Check whether or not the id exists
bool LinkedList::idExists(int id){
bool exists = false;
if (head != NULL){
Node *current = head;
while (current->forward != NULL && current->data.id != id) {
current = current->forward;
}
if (current->data.id == id) {
exists = true;
}
}
return exists;
}
You probably want to be passing a pointer to a pointer (**) or a pointer to a reference (*&) in functions where you are wanting to make a change to what the address of the node is containing. I hope that this helps you visualize it.
For example:
struct Node { };
void setNull1(Node* temp)
{
temp = nullptr;
}
void setNull2(Node** temp)
{
(*temp) = nullptr;
}
void setNull3(Node*& temp)
{
temp = nullptr;
}
int main()
{
Node* tmp = new Node;
setNull1(tmp);
if (tmp == nullptr)
{
cout << "NULLPTR";
} // tmp is not nullptr
Node* tmp1 = new Node;
setNull2(&tmp1);
if (tmp1 == nullptr)
{
cout << "NULLPTR";
} // tmp1 is nullptr
Node* tmp2 = new Node;
setNull3(tmp2);
if (tmp2 == nullptr)
{
cout << "NULLPTR";
} // tmp2 is nullptr
}
You should also consider writing nullptr instead of NULL.

How can I implement a remove function to this custom C++ List class?

I have a custom list called myList, which works like this:
// creating and adding:
myList<int> numbers;
numbers.add(10);
numbers.add(20);
// listing each item:
int n
while (numbers.nextItems(n)) {
std::cout << m;
}
And here's the source code of myList:
template<class T>
class myList
{
struct eachItem
{
T data;
eachItem *nextItem;
eachItem(eachItem *p = NULL)
{
nextItem = p;
}
}; // end of eachItem
eachItem *beginning;
eachItem *current;
myList(const myList&);
public:
myList()
{
current = beginning = new eachItem;
}
void add(const T& dat);
bool nextItems(T& dat);
~myList();
};
template <class T>
myList<T>::~myList()
{
eachItem *p;
while ((p = beginning) != NULL)
{
beginning = p->nextItem;
delete p;
}
}
template <class T>
void myList<T>::add(const T& dat)
{
eachItem *eachI;
for (eachI = beginning; eachI->nextItem != NULL; eachI = eachI->nextItem);
eachItem *newList = new eachItem(*eachI);
eachI->data = dat;
eachI->nextItem = newList;
}
template <class T>
bool myList<T>::nextItems(T& dat)
{
if (current->nextItem == NULL)
{
current = beginning;
return(false);
}
dat = current->data;
current = current->nextItem;
return(true);
}
Now, I would like to add a remove functionality to this custom list class. I would like it to work like this:
numbers.remove(10)
I had many different tries, but I couldn't get it work.
Here's my attempt:
template <class T>
void myList<T>::remove(const T& dat)
{
eachItem *eachI;
for (eachI = beginning; eachI->nextItem != dat; eachI = eachI->nextItem);
eachItem *newList = new eachItem(*eachI);
eachI->nextItem = newList;
eachItem *eachI2; // from the deleted to the actual end
for (eachI2 = eachI->nextItem; eachI2->nextItem != NULL; eachI2 = eachI2->nextItem);
eachItem *newList2 = new eachItem(*eachI2);
eachI2->nextItem = newList2;
}
Firstly your for loop condition should be eachI->nextItem->data!=dat so that you compare data, instead you were comparing address of next node and data
void myList<T>::remove(const T& dat)
{
//Special acse for deleting first node
if(beginning!=NULL && beginning->data==dat)
{
eachItem *toDelete = beginning;
beginning = beginning->nextItem;
current = beginning;
delete toDelete;
return;
}
eachItem *eachI;
for (eachI = beginning;eachI!=NULL && eachI->nextItem->data != dat; eachI = eachI->nextItem);
//if eachI=NULL then data to be deleted is not found
if(eachI==NULL)
{
cout<<dat<<" not found in this list, so not deleted\n";
return; //no further processing required.
}
//After this for eachI->nextItem will point to node that is to be deleted
eachItem *toDelete = eachI->nextItem;
//now remove link between eachI and toDelete
//i.e. let eachI->next point to toDelete->nextItem
eachI->nextItem = toDelete->nextItem;
//Therefore skipping toDelete
//Now tieing up loose ends(delete the node)
delete toDelete;
}
Also change your add function
void myList<T>::add(const T& dat)
{
if(beginning==NULL)
{
beginning = new eachItem;
current=beginning;
beginning->data = dat;
return;
}
eachItem *eachI;
for (eachI = beginning;eachI->nextItem != NULL; eachI = eachI->nextItem);
eachItem *newList = new eachItem;
newList->data = dat;
eachI->nextItem = newList;
newList->nextItem = NULL;
}
And your constructor too
myList()
{
current = beginning = NULL;
}
main function and output
int main()
{
myList<int> numbers;
numbers.add(10);
numbers.add(20);
numbers.add(30);
numbers.add(40);
int m;
while (numbers.nextItems(m)) {
std::cout << m;
}
cout<<"\n";
numbers.remove(10);
while (numbers.nextItems(m)) {
std::cout << m;
}
cout<<"\n";
numbers.remove(30);
while (numbers.nextItems(m)) {
std::cout << m;
}
return 0;
}
OUTPUT
10203040
203040
2040
I dont see where does it stucks in loop forever

Why am I getting a Redefinition of a C++ class error?

Using the following code below I am getting a "Redefinition of SortedLL" error.
So I removed "class SortedLL" from the header file below. But when I remove SortedLL from the header file then I can't declare a SortedLL in the main.cpp file.
So I am stuck. What am I missing?
Sorted Linked List header file
#ifndef SortedLinkedList_SortedLL_h
#define SortedLinkedList_SortedLL_h
struct Node {
int data;
struct Node * next;
};
class SortedLL {
public:
int find(int data);
bool remove(int data);
int size();
bool removeOdd();
bool add(int data);
private:
struct Node * pHead;
int length;
};
#endif
Sorted Linked List CPP file
#include <iostream>
#include "SortedLL.h"
class SortedLL {
private:
// searches the linked list linearly
int findLinear(int data, struct Node ** pPrev, struct Node ** pCurr){
// start at head of list
*pCurr = pHead;
*pPrev = NULL;
int index = 0;
while (*pCurr != NULL){
if ((*pCurr)->data == data){
// found
return index;
}
else {
*pPrev = *pCurr;
*pCurr = (*pCurr)->next;
index++;
}
}
return -1;
}
bool findInsertPointLinear(struct Node ** pPrev, struct Node ** pCurr, int data){
while (*pCurr != NULL){
// if current data is less then new data
if ((*pCurr)->data < data){
// store previous node
*pPrev = *pCurr;
// advance to next position
*pCurr = (*pCurr)->next;
}
// current value is >= new val
else {
// we found insertion point
break;
}
}
return true;
}
// returns the value at the index or NULL if no value exists
bool get(int index, int * val) {
// check if out of bounds
if (index < 0 || index > (length-1)) {
// out of bounds
return false;
}
struct Node * pCurr = pHead;
for (int i=0;i<=index;i++){
pCurr = pCurr->next;
}
if (val != NULL) {
*val = pCurr->data;
}
return true;
}
public:
bool add (int data) {
struct Node * pCurr = pHead;
struct Node * pPrev = NULL;
bool returnVal = true;
// if the list is empty
if (pHead == NULL){
// add the new node
pHead = (struct Node *)malloc(sizeof(struct Node));
pHead->data = data;
pHead->next = NULL;
// return success
length++;
return returnVal;
}
// the list is not empty, so find insertion point
if (findInsertPointLinear(&pPrev, &pCurr, data)){
// if inserting at the begininng of list
if (pPrev == NULL){
pPrev = (struct Node *)malloc(sizeof(struct Node));
if (pPrev != NULL) {
pPrev->data = data;
pPrev->next = pCurr;
// keep track of head pointer
pHead = pPrev;
}
else {
// failed to allocate memory
returnVal = false;
}
}
// if inserting at end of list
else if (pCurr == NULL && pPrev !=NULL) {
pCurr = (struct Node *)malloc(sizeof(struct Node));
if (pCurr != NULL){
pCurr->data = data;
pPrev->next = pCurr;
pCurr->next = NULL;
}
else {
// failure to allocate memory
returnVal = false;
}
}
// if inserting in the middle of list
else {
pPrev->next = (struct Node *) malloc (sizeof(struct Node));
if (pPrev->next != NULL){
pPrev->next->data = data;
pPrev->next->next = pCurr;
}
else {
// failure to allocate memory
returnVal = false;
}
}
}
// increment size of list by 1
if (returnVal == true)
length++;
return returnVal;
}
// returns index of first occurrence of data or -1 if not found
int find(int data){
struct Node * pPrev = NULL;
struct Node * pCurr = NULL;
return findLinear(data, &pPrev, &pCurr);
}
bool remove(int data) {
// try to find data
struct Node * pPrev = NULL;
struct Node * pCurr = NULL;
int removeIndex = findLinear(data, &pPrev, &pCurr);
bool returnVal = false;
// if found
if (removeIndex != -1){
// remove node
return false;
}
// if removing at the head
if (removeIndex == 0){
if (pCurr != NULL){
pHead = pCurr->next;
free(pCurr);
pCurr = NULL;
returnVal = true;
}
else {
printf("trying to remove an element that does not exist\n");
}
}
// if removing at the end
else if (removeIndex == (length-1)){
if (pCurr != NULL) {
free(pCurr);
pCurr = NULL;
if (pPrev != NULL){
pPrev->next = NULL;
}
returnVal = true;
}
else {
printf("trying to remove an element that does not exist\n");
}
}
// removing somewhere in the middle
else {
if (pPrev != NULL && pCurr != NULL){
struct Node * temp = pCurr->next;
free(pCurr);
pCurr = NULL;
pPrev->next = temp;
returnVal = true;
}
// something is wrong
else {
printf("attempting to remove an element from middle but either previous or curr element is NULL\n");
}
}
return returnVal;
}
int size(){
return length;
}
bool removeOdd(){
struct Node * pCurr = pHead;
struct Node * pPrev = NULL;
// iterate over list
while (pCurr != NULL){
// if current data element is odd
if (pCurr->data %2 != 0){
// remove it
// removing at head
if (pCurr == pHead){
pHead = pHead->next;
free(pCurr);
pCurr = pHead;
}
// if removing at the end
else if (pCurr->next == NULL){
free(pCurr);
pCurr = NULL;
pPrev->next = NULL;
}
// removing somewhere in the middle
else {
struct Node * temp = pCurr->next;
free(pCurr);
pPrev->next = temp;
// advance pCurr to next node
pCurr = temp;
}
}
// if current data element even
else {
pPrev = pCurr;
pCurr = pCurr->next;
}
}
return true;
}
}SortedLL;
As # PaulMcKenzie points out, you've defined the class SortedLL in both your header and your .cpp file. What you want in the .cpp is just the method definitions. Something like:
int SortedLL ::findLinear(int data, struct Node ** pPrev, struct Node ** pCurr) {
...
}

Reversing a Doubly Linked List with member function

I am trying to reverse a doubly linked list. According to other questions on stack overflow and the web this is the proper method to reverse a doubly linked list; swapping the next and back pointers of every node. For some reason it's not working for me and I can't debug it because XCode 6 has the entire debug menu grayed out. The reverse function is at the bottom of dll.cpp. Heres my code:
dll.h:
#ifndef dll_h
#define dll_h
#include <iostream>
using namespace std;
template <class ItemType>
struct NodeType
{
ItemType info;
NodeType* next;
NodeType* back;
};
template <class ItemType>
class DoublyLinkedList
{
public:
DoublyLinkedList(); // Class constructor.
~DoublyLinkedList(); // Class destructor.
////////// implement these functions //////////
DoublyLinkedList(DoublyLinkedList<ItemType>& );
void InsertItem(ItemType item);
void DeleteItem(ItemType item);
void reverseDoublyLinkedList();
void FindItem(NodeType<ItemType>* listData, ItemType item, NodeType<ItemType>*& location, bool& found);
int LengthIs() const;
void MakeEmpty();
void RetrieveItem(ItemType& item, bool& found);
void ResetList();
void GetNextItem(ItemType& item);
private:
NodeType<ItemType>* listData;
int length;
NodeType<ItemType>* currentPos;
};
#endif
dll.cpp:
#include "DLL.h"
template<class ItemType>
DoublyLinkedList<ItemType>::DoublyLinkedList()
{
listData = NULL;
length =0;
currentPos = NULL;
}
template<class ItemType>
void DoublyLinkedList<ItemType>::FindItem(NodeType<ItemType>* listData, ItemType item,
NodeType<ItemType>*& location, bool& found)
// Assumption: ItemType is a type for which the operators "<" and
// "==" are defined-either an appropriate built-in type or a
// class that overloads these operations.
// Pre: List is not empty.
// Post: If there is an element someItem whose key matches item's
// key, then found = true; otherwise, found = false.
// If found, location contains the address of someItem;
// otherwise, location contains the address of the logical
// successor of item.
{
bool moreToSearch = true;
location = listData;
found = false;
while (moreToSearch && !found)
{
if (item < location->info)
moreToSearch = false;
else if (item == location->info)
found = true;
else
{
location = location->next;
moreToSearch = (location != NULL);
}
}
}
template <class ItemType>
int DoublyLinkedList<ItemType>::LengthIs() const
{
return length;
}
template <class ItemType>
void DoublyLinkedList<ItemType>::MakeEmpty()
// Post: List is empty; all items have been deallocated.
{
NodeType<ItemType>* tempPtr;
while (listData != NULL)
{
tempPtr = listData;
listData = listData->next;
delete tempPtr;
}
length = 0;
}
template <class ItemType>
void DoublyLinkedList<ItemType>::ResetList()
{
currentPos = NULL;
}
template <class ItemType>
void DoublyLinkedList<ItemType>::GetNextItem(ItemType& item)
{
if (currentPos == NULL)
currentPos = listData;
else
currentPos = currentPos->next;
item = currentPos->info;
}
template <class ItemType>
void DoublyLinkedList<ItemType>::RetrieveItem(ItemType& item,
bool& found)
{
bool moreToSearch;
NodeType<ItemType>* location;
location = listData;
found = false;
moreToSearch = (location != NULL);
while (moreToSearch && !found)
{
if (location->info < item)
{
location = location->next;
moreToSearch = (location != NULL);
}
else if (item == location->info)
{
found = true;
item = location->info;
}
else
moreToSearch = false;
}
}
template <class ItemType>
DoublyLinkedList<ItemType>:: ~DoublyLinkedList() // Class destructor.
{
MakeEmpty();
}
template <class ItemType>
void DoublyLinkedList<ItemType>::InsertItem(ItemType item)
{
NodeType<ItemType>* node = new NodeType<ItemType>;
node->info = item;
if(!length)
{
listData = node;
node->next = NULL;
node->back = NULL;
length++;
return;
}
NodeType<ItemType>* temp =listData;
if(temp->next == NULL)
{
if(temp->info < item)
{
node->next = NULL;
node->back = temp;
temp->next = node;
}
else
{
node->next = temp;
node->back = NULL;
temp->back = node;
}
length++;
return;
}
while(1)
{
if(temp->info > item)
{
node->next = temp;
node->back = temp->back;
if(temp->back != NULL)
{
node->back->next = node;
}
if(temp->back == NULL)
listData = node;
node->back = temp->back;
length++;
return;
}
else if(temp->next == NULL)
{
node->next = NULL;
node->back = temp;
temp->next = node;
length++;
return;
}
temp = temp->next;
}
}
template <class ItemType>
void DoublyLinkedList<ItemType>::DeleteItem(ItemType item)
{
NodeType<ItemType>* node = listData;
if(node == NULL)
return;
while(node != NULL && node->info != item)
node = node->next;
if(node == NULL)
return;
if(node->back != NULL)
node->back->next = node->next;
if(node->next != NULL)
node->next->back = node->back;
delete node;
length--;
}
template <class ItemType>
DoublyLinkedList<ItemType>::DoublyLinkedList(DoublyLinkedList<ItemType>& original)
{
length = 0;
currentPos = NULL;
listData = NULL;
NodeType<ItemType>* copy = original.listData;
while(copy != NULL)
{
InsertItem(copy->info);
copy = copy->next;
}
}
template<class ItemType>
void DoublyLinkedList<ItemType>::reverseDoublyLinkedList()
{
if(listData == NULL || listData->next == NULL)
return;
NodeType<ItemType>* node = listData;
while(node!=NULL)
{
swap(node->next, node->back);
listData = node;
node = node->back;
}
currentPos = NULL;
}
main.cpp:
#include <iostream>
#include "dll.h"
#include "dll.cpp"
int main()
{
DoublyLinkedList<int> s;
s.InsertItem(3);
s.InsertItem(4);
s.InsertItem(1);
s.DeleteItem(2);
s.DeleteItem(4);
cout<<"Length of s: "<<s.LengthIs()<<endl;
DoublyLinkedList<int> t = s;
cout<<"Length of t: "<<t.LengthIs()<<endl;
t.InsertItem(5);
t.InsertItem(13);
t.InsertItem(10);
t.InsertItem(-3);
int a;
t.ResetList();
for(int i=0;i<t.LengthIs();i++)
{
t.GetNextItem(a);
cout<<"Item #"<<i<<": "<<a<<endl;
}
cout<<endl;
t.reverseDoublyLinkedList();
t.ResetList();
for(int i=0;i<t.LengthIs();i++)
{
t.GetNextItem(a);
cout<<"Item #"<<i<<": "<<a<<endl;
}
cout<<endl;
}
Unrelated but if anyone could tell me why XCode 6.1 wont let me debug on my new Macbook Pro that would be helpful too.
EDIT:
Output:
Length of s: 2
Length of t: 2
Item #0: -3
Item #1: 1
Item #2: 3
Item #3: 5
Item #4: 10
Item #5: 13
Item #0: 13
Item #1: 5
Item #2: 3
Item #3: 1
Program ended with exit code: 9
At the end it crashes on member function GetNextItem() on line item = currentPos->info;.
The issue has to do with your InsertItem. Right now, it is overly complicated.
You are attempting to insert an item in increasing order. So the easiest thing to do is take a pair of nodes, and see if the item goes in-between the pair. Here is an easier implementation:
template <class ItemType>
void DoublyLinkedList<ItemType>::InsertItem(ItemType item)
{
NodeType<ItemType>* node = new NodeType<ItemType>;
node->info = item;
if (!length)
{
listData = node;
node->next = NULL;
node->back = NULL;
length++;
return;
}
NodeType<ItemType>* temp = listData;
while (temp)
{
// get the next node
NodeType<ItemType>* nextNode = temp->next;
// make sure we have a pair of nodes
if (nextNode)
{
// test for inbetween
if (item >= temp->info && item <= nextNode->info)
{
// set the pointers and return
// make sure we set the node in-between the temp and nextNode
temp->next = node;
nextNode->back = node;
// now set node to point to temp (back), and nextNode (next)
// for the in-between to link correctly
node->next = nextNode;
node->back = temp;
// increase the length and get out
++length;
return;
}
}
else
{
// we're at the last node, so only place for this is at the back
// set the pointers and return
temp->next = node;
node->back = temp;
// last node, so make sure it points to NULL as next
node->next = NULL;
// increase length and get out
++length;
return;
}
// go to next node and get next pair
temp = nextNode;
}
}
Now, this works. Can it be better? Probably, but the point is that it is easy to understand what is going on.
If you drew on paper what is needed to be done, the above is probably closest to what you would draw on paper, i.e. get two nodes, see if the item goes in-between the two nodes, if not, get the next pair of nodes, etc...