C++ - Stack with Linked List - Bad Memory Error? - c++

I am currently writing stack that is being implemented with a linked list. I am get this error:
Unhandled exception at 0x75249617 in STACK_LinkedList.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x002ee8f8.
I believe it is possibly coming from either my push() or pop() functions. I can't find my error. I am fairly new to linked lists, so I have a little bit of a tough time finding errors.
Here is my push() function:
// Adds an item to the top of the stack
template <class S>
void Stack<S>::push(const S & e)
{
NodePointer temp = new Node(e);
if ( isEmpty() )
{
theTop = theFront = temp;
}
else
{
// Whatever is after top is stored in temp to keep track of it
theTop->next = temp;
// TheTop is stored in temp
theTop = temp;
delete temp;
}
}
Here is my pop() function:
//Takes the item off the top of the stack
template <class S>
void Stack<S>::pop()
{
if ( !isEmpty() )
{
//temp node is set equal to the front
NodePointer temp = theFront;
//Holds the second to last node in the linked list
NodePointer pred;
//loops through until the node after temp is 0
while (temp->next != 0)
{
//sets the second to last as temp
pred = temp ;
//basically "increments" temp to the next node
temp = temp->next ;
}
//sets temp equal to the top
temp = theTop;
//the top is then set to its predecessor
theTop = pred;
//deletes what was known as the top
delete temp;
}
else
cout << "STACK IS EMPTY" << endl;
}
Thanks alot! I believe most of my logic is correct. I just am missing something small. If it's something else please tell me and i'll post that code.

You should not delete your temp in push! It's a part of the list. So when you access this data later, you get surely an exception.
Second, you have to initialize your pred with NULL in pop(), otherwise you'll get an undefined value assigned to theTop if the stack contains only 1 item.
Third, you should delete in pop() the Node which you allocated in push().
In general, your approach seems to be not very efficient. You should better store the pointers other way round: from stack top to the bottom items. That way you won't need to traverse the whole stack on each pop(). Your code will be something like that:
void push(data)
{
allocate new top
new top's next is the old top
store new top in the class
}
void pop()
{
if empty, ERROR;
new top = old top's next
deallocate old top
}
Note that you don't need theFront at all.

Your push function is deleting "temp". However, temp points to the data you just added to your list. If call delete on a pointer, you are not throwing away the pointer, but rather deleting the memory it points to! Get rid of your delete statement in push and test that first (without pop). I haven't looked over your pop function, but I will leave that as an exercise for you to check for errors after you test pop().
-Dan8080

Related

Why is the delete temp crashing even though the function is defined with new

I am making a modified double ended Linked List, but the head and the tail point to each other. In the insertBeforeCurrent and the insertAfterCurrent I defined the objects with new and put them into the Linked List. But when I go to use delete, the program just crashes. I have done some tests, and insertBeforeCurrent and insertAfterCurrent works, and I am able to through the Linked List and print every single element with the getPrevious and getNext. I also printed it using only insertBeforeCurrent, insertAfterCurrent and I was also able to do the same with the mixture of the two. I was able to print it with 1,2,3,and 6 elements in the Linked List. The problem I have is the debugger, everything works until I hit the delete temp; at which point it will just say.
Can't find a source file at "/build/glibc-t7JzpG/glibc-2.30/signal/../sysdeps/unix/sysv/linux/raise.c"
Locate the file or edit the source lookup path to include its location.
I know you can only use the delete function for delete the data created by the new's dynamic memory allocation, but that doesn't seem to be the case since every element of the Linked List is created by new.
So the issue with application crashing is not the Node * x = new Node(); followed by x = y;. These don't show any warnings,the application runs, and 5 or 6 people have pointed them out. Thank you by the way. My issue is specifically is the delete temp;and why is it not being deleted. I have left the code for some context.
EDIT: I have removed the insertBeforeCurrent and insertAfterCurrent code since it is not needed.
bool CircularDoublyLinkedList::remove(int original_data)
{
Node search_data = search(original_data);
Node* temp = &search_data;
Node* current_next;
Node* current_previous;
if (temp != NULL)
{
if (temp == head)
{
current_previous = temp->getPrevious();
current_next = temp->getNext();
current_previous->setNext(current_next);
current_next->setPrevious(current_previous);
head = current_next;
temp->setNext(NULL);
temp->setPrevious(NULL);
delete temp;
current = current_next;
cout << "Delete successful." << endl;
}
else if (temp == tail)
{
current_previous = temp->getPrevious();
current_next = temp->getNext();
current_next->setPrevious(current_previous);
current_previous->setNext(current_next);
tail = current_next;
temp->setNext(NULL);
temp->setPrevious(NULL);
delete temp;
current = current_next;
cout << "Delete successful." << endl;
}
else
{
current_previous = temp->getPrevious();
current_next = temp->getNext();
current_previous->setNext(current_next);
current_next->setPrevious(current_previous);
temp->setNext(NULL);
temp->setPrevious(NULL);
delete temp;
}
return true;
}
return false;
}
I know you can only use the delete function for delete the data created by the new's dynamic memory allocation,
So far so good.
but that doesn't seem to be the case since every element of the Linked List is created by new.
This is not relevant, since the temp in CircularDoublyLinkedList::remove() never points to an element of the linked list. You assign to temp the address of a local variable (search_data) and never change that. Local variables are not created by new, so (as you noted earlier), you cannot delete &search_data.
(You might have noticed this yourself had you used a debugger to step through your code while trying to delete the first element of the list. In your current code, temp == head will never be true, even though that is the branch for deleting the first element. Similarly, temp == tail will never be true, and temp != NULL will never be false.)
At a guess, your search() function should probably return a pointer to a node in the list instead of returning the node, at which point you'll no longer need the (poorly-named) temp variable.

Linked list issue with overwriting variables

I am trying to code a linked list in C++, but I am running into a problem. When I insert only one item, it works, but when I insert more than one, it goes into an infinite loop. Here is the code:
#include "linkedList.hpp"
#include <iostream>
linkedList::node::node(int value)
{
internalValue = value;
next = nullptr;
previous = nullptr;
};
linkedList::linkedList()
: header{node(-2)}, trailer{node(-2)}
{
trailer.previous = &header;
header.next = &trailer;
size = 0;
}
int linkedList::getLength()
{
return size;
}
void linkedList::appendElement(int value)
{
node newNode = node(value);
newNode.next = &trailer;
newNode.previous = trailer.previous;
(trailer.previous)->next = &newNode;
trailer.previous = &newNode;
size = size + 1;
}
void linkedList::print()
{
node * current = header.next;
while (current -> next != nullptr)
{
std::cout << current -> internalValue << "->" << "\n";
current = current->next;
}
std::cout << "v";
}
After trying to debug it, I found that the issue is with the construction of a node. So the first time I try to insert 5, the program creates a node called new node, which is then appended perfectly fine.
What happens next is when a second number is to be appended, lets say 6, the program doesn't really create a new node object. Rather the variable name "newNode" still refers to the node with the value 5 stored in it and it replaces it with a node with the value of 6.
This understandably then creates an infinite loop since it essentially makes the array circular. I don't know how to fix this. Can someone point me in the right direction?
PS: sorry if this is extremely simple, I am very new to C++ (this is only my second day of coding)
In linkedList::appendElement(int value) you create a new node on the stack ( or 'automatic storage' ), which means the node will be destroyed when the function returns.
Instead, create the node on the heap ( or 'dynamic storage' ) using the new operator so it is not destroyed when the function returns.
node* newNode = new node(value);
You will also have to remember to destroy nodes yourself when the list is destroyed or truncated, and most C++ developers soon find it better to use smart pointers for that.

recursive deletion of linked list c++

Could you tell, why the implementation of the next code leads to the error:
void del (num*&head) {
num*temp = 0;
if (head!=0) {
temp = head;
delete temp;
del (head->next);
}
else return;
}
The error:
Access violation reading location 0xcdcdcdc1.
Whereas next code works properly:
void del (num*&head) {
if (head!=0) {
del (head->next);
delete head;
}
else return;
}
Deleting temp invalidates head, since they both point to the same object. head->next tries to access the deleted object, giving undefined behaviour. You should instead store head->next, so you don't have to access the deleted object:
if (head) {
num * temp = head->next;
delete head;
del (temp);
}
You're running a debug build, so the deleted memory was helpfully set to garbage, rather than left with its old contents. This means that trying to use values read from it as pointers will quickly trigger an access violation, helping you find the source of the problem.
The second version waits until you've finished with the object before deleting it, so there's no undefined behaviour.
However, recursion is a bad idea since it could cause a stack overflow if the list is too long. Iteration would be safer:
while (head) {
num * temp = head->next;
delete head;
head = temp;
}
You're accessing head->next while actually you already deleted head the line before.
Another way to go about this would be:
void del (num*&head) {
if (head!=0) {
num* temp = head->next;
delete head;
del (temp);
}
else return;
}
In the first version,
temp = head;
delete temp;
del (head->next);
temp and head point to the same node, then the node is deleted and becomes invalid. But it is accessed in the last line with
del (head->next);
The second version does not have this problem.
temp = head;
delete temp; // head is dead too!
del (head->next); // dereferencing disposed pointer
As far as you operate with pointers pointing to the same memory, deleting any of that pointers would make the memory deleted. So, even if you don't delete that other pointers they point to a piece of trash (or even to memory owned by another person)
Think of it in this way:-
when you have done
temp = head;// it means temp and head are talking about the same person,i.e, the same memory location.
delete temp; //the person(memory location) to which the both of them are pointing is dead;
del (head->next); //Now you trying to kill the "ghost" of the person means you are trying to delete already deleted node.
But in your second case the recursive call is just above
delete head;
so the recursive call first progresses towards the end and then nodes are deleted from the end towards the start, as follows:-
if you have n nodes, the summary of recursive call can be viewed as:-
del (list); // call from main.
del (list->head); //recursive call.
del (list->head->head);//recursive call.
del (list->head->head->head);//recursive call.
so on..................
so when last node appears its next is NULL so recursion stops and the nodes are deleted from the last call to the first call fashion in other words from the last node towards the first node. So no harm is done here as in your first case.

Stack.Pop() using LinkedList

Just so you all know this is a homework problem and I have spent hours trying to figure this little thing out. My pop() won't work. This is my current code for pop():
StackElement Stack::Pop(){
Position temp;
temp = stack.CurrentEntry();
stack.Delete();
return temp;}
I am using Delete() which is a linked list based delete() function that goes like this:
void LinkedList::Delete(){
if (current == first && AtEnd()){
// Remove the memory allocation for the element's data
delete &current->data;
// Reset all values of the linked list to original (null) state
current = NULL;
pred = NULL;
first = NULL;
}
else
// Checks if the current element is the first node in the lists
if (current == first){
// Make new first element to be the next element
first = current->next;
// Remove the memory allocation for the element's data
delete &current->data;
// The new current entry is the successor of the deleted node.
current = first;
}
// When the element you're deleting is not the first node in list
else{
assert(!Empty());
// Temporary node to prevent current from being marroned
Node *tempNode = current->next;
pred->next = tempNode;
// Remove the memory allocation for the element's data
delete &current->data;
current = tempNode;
}
}
When I compile, it throws me this error right here:
Unhandled exception at 0x003E5F79 in Program5_test.exe: 0xC0000005: Access violation writing location 0xF495EE12.
You didn't show us CurrentEntry, but I bet it just returns a pointer instead of making a full copy. Then you delete the original leaving the pointer pointing at nothing. It crashes when you use the pointer returned from Pop.

Circular Singly Linked List: Remove a particular Node from List

I wrote the code to remove a particular node from list according to user
choice, code works perfectly fine for a particular value but if i make
several calls to it meaning if I call it 2 times continuously then one of my
another function pointer_to_node(index) gives an out of bounds error which
was also implemented by me to record such conditions,
Actually, why I need several calls is that I have to write a separate function
to remove all the nodes. I am trying to accomplish that task using this
function by using a for loop up to the size of my Circular Singly Linked list.
But in that case it also returns me a NULL pointer and gives me out of bounds
message (implemented by me in code). I have included both my functions down
here
void remove_from_index(int index){
Node*temptr;
temptr = new Node;
int tempdata;
if (index==1)//means remove from first
{
temptr = firstptr;
tempdata= temptr->data;
firstptr = firstptr->nextptr;
lastptr->nextptr=firstptr;
delete(temptr);
} else if(index==size_of_list()) //means last node
{
temptr = pointer_to_node(index);
index--; //get pointer of 2nd last position
lastptr = pointer_to_node(index);//setting 2nd last as last postion
temptr->nextptr=NULL;
temptr=NULL;
lastptr->nextptr=firstptr;
delete (temptr);
} else // any position of node
{
temptr = pointer_to_node(index);
tempdata = temptr->data;
index--; // to get address of back
Node* temp2ptr;
temp2ptr = new Node;
temp2ptr = pointer_to_node(index);
index = index+2;
Node* temp3ptr;
temp3ptr = new Node;
temp3ptr = pointer_to_node(index);
temp2ptr->nextptr = temp3ptr;
temptr->nextptr=NULL;
delete (temptr);
}
}
Node* pointer_to_node(int index){
Node*temptr;
temptr = new Node;
temptr = firstptr;
Node*temptr2;
temptr2 = new Node;
temptr2 = NULL;
int count = 1;
while (temptr!=temptr2){
if (count==index)
{
return temptr;
}
count++;
temptr2=firstptr;
temptr=temptr->nextptr;
}
if (index>size_of_list())
{
temptr=NULL;
cout<< "Can't You think in bounds. Take your NULL Pointer ";
return temptr;
delete temptr;
delete temptr2;
}
}
You have several memory leaks:
temptr->nextptr=NULL;
temptr=NULL; // BAD!! BAD!! Remove it otherwise you will not actually free
lastptr->nextptr=firstptr;
delete (temptr);
And here too (actually you have this in four places of the code):
Node* temp2ptr;
temp2ptr = new Node; // BADD!! Why do you allocate if you are going to reassign?
temp2ptr = pointer_to_node(index);
Remove the bads and you will avoid the memory leaks.
Still, this is not going to fix your problem.
Also you have operations after return here:
return temptr;
delete temptr;
delete temptr2;
These are never going to be executed.
EDIT Your pointer_to_node function is too complex please change it with
Node* pointer_to_node(int index) {
Node* tempPtr = firstptr;
for (int i = 0; i < index; i++) {
tempPtr = tempPtr->nextptr;
}
return tempPtr;
}
And see if this will fix your problem. More lines of code very rarely means better programming skills, do not artificially try to increase their count.
I think another possible issue here, aside from all the memory leaks and style issues which are already well documented, is that your code does not seem to handle the case of there only being one thing in the list.
If that happens, it will delete that node, but leave firstptr and lastptr pointing at random memory.
If your size_of_list() function is just counting nodes in the list, it will probably still think there are non-zero nodes remaining, and you might then attempt to remove or otherwise access another node.