Deleting a node in a linked list C++ - c++

So I'm having a hard time getting this to work, and even after extensive googling I can't quite get it to work. Here's the function I'm working on :
bool deleteOneOf(const std::string & target)
{
Node * ptr = _first;
Node * temp;
while (ptr != nullptr)
{
if (target != ptr->_entry)
{
temp = ptr;
ptr = ptr->_link;
}
else
{
temp->_link = ptr->_link;
delete ptr->_link;
return true;
}
}
return false;
}
The Node class I have to work with is this:
class Node
{
public:
std::string _entry;
Node * _link;
Node(std::string entry, Node * link) : _entry(entry), _link(link)
{}
};
Any help is greatly appreciated, thanks.

You haven't initialized temp. If you are looking at the first element in the list, it will point to garbage. Also, you need to delete ptr. Fixed code:
bool deleteOneOf(const std::string & target)
{
Node * ptr = _first;
Node * temp = nullptr;
while (ptr != nullptr)
{
if (target != ptr->_entry)
{
temp = ptr;
ptr = ptr->_link;
}
else
{
if (temp)
temp->_link = ptr->_link;
else
_first = ptr->_link;
delete ptr;
return true;
}
}
return false;
}

Related

C++ Issue with deleting item from linked list

Previous issue resolved!
New issue: the code itself. I've been working on the code for a function to delete a selected item off a linked list, how many times it may appear. However, when I run that part of the program to try to delete a node, it'll just end the program. I know something's bound to be off but even looking at tutorials on this, I'm not quite grasping how to achieve this instruction. Any help would be greatly appreciated. [RESOLVED]
Function
void LinkedList::deleteItem(int _newItem)
{
if(isEmptyList())
cout << "\t<ERROR> List is empty.\n";
else
{
bool itemDelete = false;
nodeType *q = first;
while(q != NULL)
{
if(first->info == _newItem)
{
nodeType *p = first->link;
first->link = p->link;
delete p;
--count;
itemDelete = true;
}
if(q->link->info == _newItem)
{
nodeType *r = q;
nodeType *p = q;
r = r->link;
p->link = r->link;
delete r;
--count;
itemDelete = true;
}
q = q->link;
}
if(itemDelete == true)
cout << "Item was deleted.";
else
cout << "Item was not found.";
}
}
Class and struct
struct nodeType
{
int info;
nodeType *link;
};
class LinkedList
{
public:
void initializeList();
bool isEmptyList();
void printList();
int findLength();
void destroyList();
int infoFirst();
int infoLast();
bool searchItem(int);
void insertFront(int);
void insertBack(int);
void deleteItem(int);
int calcTotal();
int calcAvg();
LinkedList();
private:
nodeType *first, *last, *newNode;
int count; //adds or remove one whenever a node is added or removed
};
One issue with your code is this line:
if(q->link->info == _newItem)
you are accessing the next link in your linked list but that next link may be nullptr:
if(q->link != nullptr && q->link->info == _newItem)
Before you access its member info you should first check to see if it is nullptr.
You should also consider moving:
if(first->info == _newItem)
{
nodeType *p = first->link;
first->link = p->link;
delete p;
--count;
itemDelete = true;
}
outside the loop because you will go through this check everytime that you enter the loop if the node that you are trying to remove is not the first one since you are checking the node first, instead of the node q which you are using to loop through your linked list.
Also please consider using nullptr instead of NULL.
else
{
bool itemDelete = false;
nodeType *q = first;
if(first->info == _newItem)
{
nodeType *p = first->link;
first->link = p->link;
delete p;
--count;
itemDelete = true;
}
// by doing !itemDelete you will exit once you find the item
// or you won't enter the loop if the item was the first in the list
while(q != nullptr && !itemDelete)
{
if(q->link != nullptr && q->link->info == _newItem)
{
nodeType *r = q;
nodeType *p = q;
r = r->link;
p->link = r->link;
delete r;
--count;
itemDelete = true;
}
q = q->link;
}
if(itemDelete == true)
cout << "Item was deleted.";
else
cout << "Item was not found.";
}
This portion here can be further collapsed:
// by doing !itemDelete you will exit once you find the item
while(q != nullptr && !itemDelete)
{
if(q->link != nullptr && q->link->info == _newItem)
{
nodeType *r = q;
nodeType *p = q;
r = r->link;
p->link = r->link;
delete r;
--count;
itemDelete = true;
}
q = q->link;
}
to:
// by doing !itemDelete you will exit once you find the item
while(q->link != nullptr && !itemDelete)
{
if(q->link->info == _newItem)
{
nodeType *r = q;
nodeType *p = q;
r = r->link;
p->link = r->link;
delete r;
--count;
itemDelete = true;
}
q = q->link;
}
I hope that this helps you.

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

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

Linked list C++

I have to ADD a node to the end of a Linked LIST, it's not throwing any errors so far, but apparently it's not working too. I've looked into others answers, but couldn't see what's wrong with mine.
I think that the problem might be with getNext() and NULLs.
ps: I'm using HPP
Here's the method :
// ADD a node to the end of the Linked list
void add(const T& dado)
{
Elemento < T > *novo = new Elemento<T>(dado, NULL);
if (novo == NULL)
{
throw 2;
}
if (head->getNext() != NULL)
{
Elemento < T > *auxi = new Elemento<T>(dado, head->getNext());
int i;
for (i = 0; auxi->getNext() == NULL; i++)
{
auxi->setNext(auxi->getNext());
if (auxi->getNext()() == NULL)
{
size++;
auxi->setNext(novo);
}
}
}
else
{
size++;
head->setNext(novo);
}
}
My elemento class is as follow:
#ifndef ELEMENTO_HPP
#define ELEMENTO_HPP
template<typename T>
class Elemento {
private:
T *info;
Elemento<T>* _next;
public:
Elemento(const T& info, Elemento<T>* next) : info(new T(info)), _next(next) {}
~Elemento() {
delete info;
}
Elemento<T>* getNext() const {
return _next;
}
T getInfo() const {
return *info;
}
void setNext(Elemento<T>* next) {
_next = next;
}
};
#endif
You can see the whole code here: http://pastebin.com/7yJfsK8j
(method names in Portuguese, but there are comments to explain).
Try this for-loop:
Elemento<T> *ptr;
//Will iterate until ptr-> getNext() is null (this means ptr is not null).
for(ptr = head; ptr -> getNext() != NULL; ptr = ptr -> getNext())
{
//Does nothing.
};
ptr -> setNext(novo);
size++;
Hope it works!

What is the error in return statement in the following code of C++?

Chain Chain::insert(int x) {
ChainNode * current = first;
ChainNode * ptr = new ChainNode;
ptr->data = x;
ptr->link = NULL;
if(first != NULL) {
while(current->link != NULL) {
current = current->link;
}
current->link = ptr;
return * this;
}
else {
first = ptr;
return * this;
}
}
The above code doesn't work without adding '&' (reference) in return statement i.e. it gives wrong results. Here, Chain is a class used to implement linked list and ChainNode is another class which corresponds to Node of linked list.

Deep copying Queue using nodes runtime error

I'm trying to perform a deep copy for my Queue (FIFO) using nodes and I'm getting an error and Don't know what's causing it. All the methods work fine when I don't copy anything but as soon as I try to copy I get a "MyQueue.exe" stopped working. This happens when I don't even use the methods. It also happens even if I comment out the whole do-while loop. Anyone know what's causing this?
MyQueue::MyQueue (void)
{
head = NULL;
queueSize = 0;
}
MyQueue::MyQueue (const MyQueue & myq)
{
copyQueue (myq);
}
MyQueue & MyQueue::operator = (const MyQueue & myq)
{
copyQueue (myq);
return *this;
}
void MyQueue::copyQueue (const MyQueue & myq)
{
head = NULL;
queueSize = 0;
Node* temp = myq.head->next;
do
{
enqueue(myq.head->data);
temp = temp->next;
}
while ( temp->next != NULL );
}
MyQueue::~MyQueue (void)
{
}
void MyQueue::enqueue (const int n)
{
Node* temp = tail;
tail = new Node (n);
queueSize++;
if ( empty() )
{
head = tail;
}
else
{
temp->next = tail;
}
}
int MyQueue::dequeue (void)
{
if ( !empty() )
{
int result = head->data;
Node* temporary = head;
head = (temporary->data, temporary->next);
queueSize--;
return result;
}
else
{
std::cout << "No Items to remove" << std::endl;
return NULL;
}
}
int MyQueue::peek (void)
{
return head->data;
}
bool MyQueue::empty (void)
{
if ( head == NULL || queueSize == 0)
{
return true;
}
return false;
}
This is how my node is copied
Node & Node::operator = (const Node* & nd)
{
data = nd->data;
next = nd->next;
}
MyQueue q1;
MyQueue q2 = q1; // Crash.
This will crash, because the head is NULL, and you dereference it in the copyQueue() method.
Node* temp = myq.head->next;