Exception Handled this was Nullptr? - c++

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

Related

How to delete an object ( node ) which is in use

I have the following code that inserts item to a double-linked list using iterator. This is how we are asked to do it. The code works, but the problem is that I have absolute memory leak of 24 bytes.
NodeIterator<T> insert(NodeIterator<T> & itrPassed, const T datapassed)
{
Node<T> * newNode = new Node<T>(datapassed);
Node<T>* previousOfCurrent = itrPassed.getCurrent()->previous;
previousOfCurrent-> next = newNode;
newNode -> previous = previousOfCurrent;
newNode -> next = itrPassed.getCurrent();
itrPassed.setCurrent(newNode);
return itrPassed;
}
I know that the problem is caused by this line Node<T> * newNode = new Node<T>(datapassed);. I can't delete the newNode object as I am returning an iterator pointing to it and it is used in my linked list.
How to solve this problem ?
One problem I see is that you are not updating the previous of the current node. The previous of the current node still points to the old node. As a consequence, if you are iterating over the nodes using previous, you are going to skip over the newly created node.
The other problem I see is that you are accessing previousOfCurrent without checking whether it is a valid pointer.
Not sure whether fixing them will fix your memory leak problem.
NodeIterator<T> insert(NodeIterator<T> & itrPassed, const T datapassed)
{
Node<T> * newNode = new Node<T>(datapassed);
Node<T>* previousOfCurrent = itrPassed.getCurrent()->previous;
// Prevent accessing a nullptr
if ( previousOfCurrent != nullptr )
{
previousOfCurrent-> next = newNode;
newNode -> previous = previousOfCurrent;
}
newNode -> next = itrPassed.getCurrent();
// Add this
itrPassed.getCurrent()->previous = newNode;
itrPassed.setCurrent(newNode);
return itrPassed;
}

[in-place]linkedlist cannot append Node to the tail, Unhandled exception :Access violation

everyone! I'm currently building my own linkedlist class. And I find it rather troublesome to append a Node to the tail.
I'm doing the append operation in-place and I don't want to use new. I'm breaking Nodes from an old linkedlist and appending them to the tail of a new list. My code looks like:
void MyList::partition_x_3(int x) {
Node* p_prev=getHead();//p_prev is the head of the old list. Each time I break the next node and append the node to the newlist's head or tail.
Node* p1=p_prev->next;
int i=0;
MyList temp_list;
while(p1 != NULL){
cout<<"i="<<i++<<endl;
Node* p_temp=p1->next;//p_temp saves the position of p1
p_prev->next=p_temp;//
if(p1->data > x) { //this block works!
temp_list.insert_after_head(p1);
}
else { //append the p1 node to the tail of temp_list
Node* temp_tail=temp_list.getTail();
if(tail==NULL){
head->next=p1;
temp_tail=p1;
temp_tail->next=NULL;
}
else{
temp_tail->next=p1;//the break point is here!
p1->next=NULL;
temp_list.setTail(p1);
}
}
p1=p_temp;
}
cout<<"DONE"<<endl;
temp_list.traverse();
}
note that partition_x_3 is a member function of MyList class.
The problem is: when I compile, VS2012 reports an error saying that
Unhandled exception at 0x01319D6D in CareerCup.exe: 0xC0000005: Access violation writing location 0x00000004.
and breaks at the break point shown in my code.
I've Googled. However, most suggestions were like this:
<!-- language: c++ -->
Node *newNode = new Node(entry, NULL, tail);
if (tail)
tail->next = newNode;
tail = newNode;
++node_count;
But I want to do it in-place, and don't want to use new.
Could anyone help me? I'll be waiting online.

Can't Delete My Temporary Pointers?

I'm having an issue with deleting pointers. I don't think I'm doing anything compiler illegal or anything, but perhaps I am, so I would appreciate it if someone could explain the flaw in my logic. I'm hoping the below function should be enough to help, as the whole thing would be a lot to transcribe, but if any more of the code is required, please let me know and I'll add it!
The below is a function to remove lockers from a linked list I've created. I've done my best to cover every conceivable case. The problem arises when I try to actually deallocate the memory of a locker I want to delete. The lines where I've tried to delete the temp variable that references that locked are commented out, because the code breaks with them included. Obviously, though, without them, I can't delete the lockers like I want.
int SelfStorageList::removeLockersOverdue() {
int lockersDeleted = 0;
if (isEmpty()) {
return 0;
}
if (head->objLocker.isRentOverdue && head==tail) { //If that was the only locker, the tail needs to be updated to = head = 0
delete head;
head = tail = 0;
return ++lockersDeleted;
}
LockerNode *prev = head;
LockerNode *curr = head->next;
while (curr != 0) {
if((curr == tail) && curr->objLocker.isRentOverdue) { //If the current locker is tail and needs deleting
LockerNode *temp = curr;
curr = prev;
//delete temp;
lockersDeleted++;
}
if(prev->objLocker.isRentOverdue) { //General case: Previous locker needs deleting
LockerNode *temp = prev;
prev = prev->next;
curr = curr->next;
//delete temp;
lockersDeleted++;
}
else { //Update the pointers if not updated anywhere else
prev = prev->next;
curr = curr->next;
}
}
return lockersDeleted;
}
Any "pointers"? (Terrible pun. :p )
Because you're maintaining a singly-linked list, I see you're keeping track of a prev pointer as you're iterating through your list. That's as it should be, of course, since you can't get the previous node of a given node in a linked list if it's singly-linked without remembering what its previous node was. Your problem is simply that your logic is busted: If a deletion is needed, you need to be deleting the curr node, and patching up the prev node to point its next pointer to curr->next before you delete curr.
Think about it: What you're doing is deleting the prev node, but there's likely a "more previous than that" node that's still pointing to the prev node that you just deleted. The next time you iterate through the list, you'll be iterating into formerly allocated nodes, which may be allocated for some entirely different purpose by that point. Your memory allocator is failing some internal assertion because likely on the next time you call removeLockersOverdue(), the memory has NOT yet been allocated to something else, and you're still finding the same node there that you already deleted, and finding again that it's overdue, and deleting it again, and your memory allocator is complaining that you're deleting memory that isn't allocated. (It would be really nice if it gave you that clear of a message, wouldn't it!)
Also, your special case stuff for handling the very first node & last node can be simplified & commonized; I'll avoid rewriting it for you so you can see if you can simplify it yourself.
while (curr != 0) {
if((curr == tail) && curr->objLocker.isRentOverdue) {
LockerNode *temp = curr;
curr = prev;
//delete temp;
lockersDeleted++;
}
You are not updating the previous node's next pointer here, so it ends up dangling (pointing to memory that is deleted). You also leave tail pointing at the deleted node.
if(prev->objLocker.isRentOverdue) {
LockerNode *temp = prev;
prev = prev->next;
curr = curr->next;
//delete temp;
lockersDeleted++;
}
Again, you don't update the next pointer in the list that points at the deleted node.
else { //Update the pointers if not updated anywhere else
prev = prev->next;
curr = curr->next;
}
}
I think you are greatly confusing yourself by carrying around two pointers in the loop. Try to write it again with just a single pointer tracking the node you are currently examining, and draw some pictures of the three possible cases (remove first node, remove last node, remove internal node) to ensure you are getting the removal logic right.

Inserting at the tail of a doubly linked list

I'm working with linked lists for my first time and have to create a function that can insert a node at the end of a doubly linked list. So far I have
void LinkedList::insertAtTail(const value_type& entry) {
Node *newNode = new Node(entry, NULL, tail);
tail->next = newNode;
tail = newNode;
++node_count;
}
The Node class accepts a value to be stored, a value for the next pointer to point to, and a value for the previous pointer in that order. Whenever I try to insert a node here, I get an error saying there was an unhandled exception and there was an access violation in writing to location 0x00000008.
I'm not entirely sure what's going wrong here but I assume it has something to do with dereferencing a null pointer based on the error message. I would really appreciate some help with solving this problem.
EDIT:
I should have clarified early, tail is a pointer that points to the last node in the list. Tail->next accesses the next variable of that last node which, before the function runs, points to NULL but after it executes should point to the new node created.
Where does tail point to initially? If it's NULL then you'll dereference a null pointer when trying to insert the first element.
Does it help if you test tail before dereferencing it?
void LinkedList::insertAtTail(const value_type& entry) {
Node *newNode = new Node(entry, NULL, tail);
if (tail)
tail->next = newNode;
tail = newNode;
++node_count;
}
If tail is null and offsetof(Node, next) is 8 that would explain the access violation, because tail->next would be at the address 0x00000000 + 8 which is 0x00000008, so assigning to tail->next would try to write to memory at that address, which is exactly the error you're seeing.
Assuming your LinkedList has both a head AND tail, maybe try:
void LinkedList::insertAtTail(const value_type& entry)
{
Node *newNode = new Node(entry, NULL, tail);
if (tail)
tail->next = newNode;
tail = newNode;
if (!head)
head = newNode;
++node_count;
}
Just a shot in the dark
It's difficult to tell what's causing the error without knowing the state of the list before the insertion operation (which is actually append rather than insert, by the way).
There's a good chance you're not handling the initial case of appending to an empty list. The basic algorithm is (an empty list is indicated by a NULL head pointer, everything else is indeterminate):
def append (entry):
# Common stuff no matter the current list state.
node = new Node()
node->payload = entry
node->next = NULL
# Make first entry in empty list.
if head = NULL:
node->prev = NULL
head = node
tail = node
return
# Otherwise, we are appending to existing list.
next->prev = tail
tail->next = node
tail = node

Remove all nodes in linked list

I have a linked list contains 3 nodes like the image shown:
There is a head pointer and temp1 pointer point to the front of the list, and tail point points at the end of the list.
I want to remove all the nodes, and change it back to its original initial form ( tail = NULL, head = first_node , but the first node doesn't have any value in the data and next field).
Because I want to start putting up some new values in it. To remove all those data, is this code going to remove nodes inside this linked list and left with the first node with no values in data and next field?
This code is in C++:
while(temp1!=tail)
{
temp1 = temp1->next;
if(temp1->next == tail)
{
tail=temp1;
temp1 = temp1->next;
free(temp1);
}
}
But then, does this mean only the last node will be deleted? are there any way to delete all the nodes except the first one?
To delete all nodes except the first node, you can try below code.
temp1 = head->next;
while(temp1!=NULL) // as I am considering tail->next = NULL
{
head->next = temp1->next;
temp1->next = NULL;
free(temp1);
temp1 = head->next;
}
This will delete all nodes except first one. But the data with the first node will remain as it is.
Disclaimer: I assume it's only for learning purposes and in real-world scenario you would use std::list<> or similar container.
For single-linked list, you can just drop all this burden an let the stdlib manage the pointers:
class Node {
std::unique_ptr<Node> next;
};
You can safely use .reset() method to make operations on the list:
Given current_ptr, the pointer that was managed by *this, performs the following actions, in this order:
Saves a copy of the current pointer old_ptr = current_ptr
Overwrites the current pointer with the argument current_ptr = ptr
If the old pointer was non-empty, deletes the previously managed object if(old_ptr != nullptr) get_deleter()(old_ptr).
From http://en.cppreference.com/w/cpp/memory/unique_ptr/reset.
And that's pretty much what you would do when deleting. I believe you can also use unique_ptr::swap(), to easily manipulate your nodes.
Instead of free, C++ uses delete function.
Check the link to have deep knowledge about all kind of operations(including recursive or iterative delete) on linked lists.
temp1 = head->next;
while(temp1!=NULL) // as I am considering tail->next = NULL
{
head->next = temp1->next;
temp1->next = NULL;
free(temp1);
temp1 = head->next;
}
The logic for this would be more correct if it is this way.
After the statement
free(temp1);
Add the condition
if (head -> next != NULL)
temp1 = head->next;
Since after deleting the last node there is no point in reassigning the address of head pointer to temp1.