Stack.Pop() using LinkedList - c++

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.

Related

Exception Handled this was Nullptr?

I've been working on this assignment, and been running into this bug I haven't been able to fix for hours. It's saying unhandled exception thrown, read access violation. I heard you're not suppose to deference nullptrs, however I don't believe that's what I'm doing.
void Linkedlist::insertnode(string key, string value) {
Node* newNode; //This points to the following node
Node* cursor; //This will traverse through list
newNode = new Node; //create a new node
newNode->data = new HashEntry(key, value); //Initialize the data
newNode->next = nullptr; //Leave the pointer for the node following after empty at inception;
if (!head) {
head = newNode; //if head is empty, this will make the first user input the head
return;
}
else {
cursor = head;
while (cursor->next)
;
//We'll traverse list to add newNode to tail
cursor->next = newNode; //for now the order doesn't matter since they're strings so we add new cluster to tail
}
}
"read access violation" is most likely an uninitialized variable. It happens when you try to access data from memory outside your program memory. This is a protection mechanism of your system to prevent you from overwriting data you shouldn't.
Therefore I'd recommend checking your definition of the class HashEntry as well as the definition of the Pointer head which isn't in your posted code.
What also came in my view is your infinite loop while (cursor->next);
I get what you're trying to do - iterate over the elements until you're at the end of the list. But you have to use an iterator:
Node* iterator = cursor;
while (iterator)
{
iterator = iterator->next;
}

c++ link list remove all method is leaving last element unremoved

I have developed a function to remove all nodes from linked list. All nodes are successfully deleted except the last one. Please help me why last node is not being deleted? Following is my code:
void StudentLinkList::removeAll() {
StudentData *traversePointer = this->head;
while (this->head->getNext() != nullptr) {
this->head = this->head->getNext();
delete traversePointer;
traversePointer = this->head;
}
delete this->head;
}
So close
void StudentLinkList::removeAll() {
StudentData *traversePointer;
// Continue while there are any elements on the list
// Extra parens to indicate that we want the result of the
// assignment as boolean. No need to compare to nullptr.
while ( (traversePointer = this->head) ) {
// First preserve the rest of the list
this->head = this->head->getNext();
// only then can we delete this node
delete traversePointer;
}
// list is now empty
}
You're deleting this->head, but you should set this->head to nullptr as well. While you're freeing the memory the node is using, the data stored in the node's old location usually isn't immediately overwritten, which is why it looks like the last node is not deleted.
EDIT: downvote is duly noted, could someone clarify what I got wrong?
Also, I agree with the above comment - you should also check if this->head is null before the loop.

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.

Crash when deleting nodes in a circular list

I got some problems with the algorithm for "clearing" nodes in a circular list: most of times the program crashes and sometimes not. I'm quite sure that the algorithm is ok and I have no clue about the solution... :-(
Here some piecies of code:
The clear() function (Note: mFreenode is the "head-tail free" node for the circular list):
List* clear() {
if (mFreenode->getNext() != 0) {
Node<T>* current = mFreenode->getNext();
Node<T>* temp = 0;
while (current != mFreenode) {
temp = current->getNext();
delete current;
current = temp;
}
}
mFreenode->setNext(0);
mFreenode->setPrev(0);
mSize = 0;
return this;
}
And this is the Node destructor:
~Node() {
delete &item;
}
Any suggestion?
Your destructor looks very suspicious -- I'm assuming that item is a member variable of Node. If item is a value type (eg int or std::string), then you shouldn't be deleting it at all. If it's a pointer, then perhaps you should be doing delete item; -- but only if the Node has ownership of the item that it has a pointer to.
When you delete item; you do not make the previus Node to point to the Node after the Node you delete. As a result the Node previus to the one you delete points to nowhere.
Please never do the following with a circular linked list:
while (current != mFreenode) {
temp = current->getNext();
delete current;
current = temp;
}
Why do you think it is a circular linked list?? Because the tail node points to the first one, so when you do that the loop will go ahead and delete all nodes except the node before current.
and then you try to access it bad idea:
mFreenode->setNext(0);
mFreenode->setPrev(0);

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

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