Merging two linked lists throws _CrtlsValidHeapPointer(block) in MSVC - c++

I am teaching myself data structures in C++ and my current challenge is to create, and merge, two linked lists. However, Microsoft Visual Studio throws the following error:
Debug Assertion Failed! Program: LinkedList\Debug\LinkedList.exe File: minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp Line: 904 Expression: _CrtlsValidHeapPointer(block)
However, it seems to work fine in Wandbox: Source code in Wandbox Online Compiler Where does it go wrong?
This is the source code:
#include <iostream>
#include <cstdlib>
class Node {
public:
int data;
Node* next;
};
class LinkedList {
public:
LinkedList() {
head = nullptr;
}
~LinkedList() {
Node* temp = head;
while (head) {
head = head->next;
delete temp;
temp = head;
}
};
void addNode(int value);
void display();
void merge(LinkedList& list2);
private:
Node* head;
};
void LinkedList::addNode(int value) {
Node* newnode = new Node();
newnode->data = value;
newnode->next = nullptr;
if (head == nullptr) {
head = newnode;
} else {
Node* temp = head; // head is not NULL
while (temp->next != nullptr) {
temp = temp->next; // go to end of list
}
temp->next = newnode; // linking to newnode
}
}
void LinkedList::display() {
if (head == nullptr) {
std::cout << "List is empty!" << std::endl;
} else {
Node* temp = head;
while (temp != nullptr) {
std::cout << temp->data << " ";
temp = temp->next;
}
std::cout << std::endl;
}
}
void LinkedList::merge(LinkedList& list2) {
Node* node = new Node();
node->next = nullptr;
Node* temp = node;
Node* head1 = head;
Node* head2 = list2.head;
while (head1 != nullptr && head2 != nullptr) {
if (head1->data <= head2->data) {
temp->next = head1;
temp = temp->next;
head1 = head1->next;
} else {
temp->next = head2;
temp = temp->next;
head2 = head2->next;
}
}
while (head1 != nullptr && head2 == nullptr) {
temp->next = head1;
temp = temp->next;
head1 = head1->next;
}
while (head2 != nullptr && head1 == nullptr) {
temp->next = head2;
temp = temp->next;
head2 = head2->next;
}
temp = temp->next;
delete temp;
head = node->next;
}
int main() {
LinkedList list;
list.addNode(1);
list.addNode(2);
std::cout << "Linked List Data: " << list.display() << std::endl;
LinkedList list2;
list2.addNode(3);
list.merge(list2);
list.display();
return 0;
}

That MSVC error indicates that you're doing something bad with memory. In this case it seems you're deleting memory twice. Freeing a pointer twice is Undefined Behavior and compilers/runtimes are not required to diagnose the problem.
Your merge seems to be expecting sorted lists, but addNode does not enforce this. Also, once that merge is done, the nodes of list2 will be contained in both the returned list and the original list2. When the LinkedList destructor runs you will (try to) delete those nodes twice. The Microsoft Compiler in Debug builds can tell you about these problems.
There are also issues with memory leaks (e.g., the node allocated in merge is not freed).

The Expression: _CrtIsValidHeapPointer(block) indicates that memory has corrupted, possibly due to writing past the end of a buffer or writing past the end of a class because the writer assumes the class is larger than was allocated (like when it is expecting a derived class and gets a base class, or object of a different class).
Please open Debug->Windows->Exception Settings, In the Exception Settings window, expand the node for a category of exceptions -> Common Language Runtime Exceptions( meaning .NET exceptions), and select the check box for a specific exception within that category System.AccessViolationException. You could also select an entire category of exceptions if you don't know which exception to choose. And then you could see the initial problem.
For more information about how to manage exceptions, please refer to this document below:
https://learn.microsoft.com/zh-cn/visualstudio/debugger/managing-exceptions-with-the-debugger?view=vs-2019&redirectedfrom=MSDN

Related

Error C6011:Dereferencing NULL pointer 'NAME'. C++

As in the title my code gives the said warning and mashes up the memory references.
I was tasked with using nested classes in C++. This code is mostly my code for linked lists from a previous C application but remade for C++.
I ve searched on the internet about said NULL exception and I can t figure it out.
I ll post the code and hope someone can give me some tips.
In the various links and tips on the internet it says that the pointer I am pointing to is referencing to a NULLptr, and that it can t accces a NULL address.
Tried to review it in various forms but it doesn t work.
Header
#ifndef LIST_H
#define LIST_H
#include <iostream>
#include <math.h>
using namespace std;
class List
{
private:
class Node {
public:
int data;
Node* next;
Node() {
this->data = NULL;
this->next = NULL;
}
};
Node* head;
public:
List();
void insertList(int data);
void deleteFromList(int data);
void deleteLowerThan(int lower);
void calculateArithmetic();
void showList();
};
#endif
Cpp file
List::List() {
this->head = NULL;
}
void List::insertList(int n) {
Node* new_node = new Node();
new_node->data = n;
new_node->next = head;
head = new_node;
}
void List::deleteFromList(int n) {
Node* temp = head;
Node* prev = NULL;
if (temp != NULL && temp->data == n) {
head = temp->next;
return;
}
while (temp->data != n && temp != NULL) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) return;
prev->next = temp->next;
}
void List::deleteLowerThan(int n) {
Node* temp = head;
while (temp != NULL) {
if (temp->data < n) {
deleteFromList(temp->data);
}
else {
temp = temp->next;
}
}
}
void List::showList()
{
Node* temp = head;
while (temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
}
Driver
int main() {
List lista;
lista.insertList(2);
lista.insertList(4);
lista.insertList(6);
lista.insertList(8);
lista.insertList(3);
lista.insertList(1);
lista.insertList(-4);
lista.showList();
lista.deleteFromList(4);
lista.showList();
lista.deleteFromList(8);
lista.showList();
lista.deleteFromList(6);
lista.showList();
lista.deleteLowerThan(3);
lista.showList();
return 0;
}
The problem lies in your deleteFromList function, with this code:
while (temp->data != n && temp != NULL) {
//...
Here, you are trying to check the value of temp->data before you have verified whether or not temp is NULL. Thus, you will, at some point (when you're at the end of the list, and temp is NULL be dereferencing a null pointer - which ain't good!
Instead, just invert the order of the comparisons:
while (temp != NULL && temp->data != n) {
//...
This way, as soon as temp is NULL, the comparison's result will be fully known (see short circuiting), temp->data will not be evaluated, and the loop will stop running.
As pointed out by Adrian and Andy, this line causes temp to be dereferenced before you check if it's NULL:
while (temp->data != n && temp != NULL)
so, just check that it's not NULL first, then dereference it.
Other mentionable problems are the memory leaks. You should have exactly one delete for each new (unless you surrender the pointer to a smart pointer that will do delete for you).
void List::deleteFromList(int n) {
Node* temp = head;
Node* prev = head; // set this if you need to delete head
if(temp != nullptr && temp->data == n) {
head = prev->next;
delete prev; // you forgot this
return;
}
while(temp != nullptr && temp->data != n) {
prev = temp;
temp = temp->next;
}
if(temp == nullptr) return;
prev->next = temp->next;
delete temp; // you forgot this
}
You also need to implement a destructor in List to delete all the nodes in the List when it is destroyed.
A trickier bug is in your deleteLowerThan() function. You iterate over the nodes in your list and call deleteFromList() which will delete the very node you are currently on. In the next iteration, you use the same node pointer in if (temp->data < n) { causing undefined behaviour. In my case, the program seemed to just hang forever.
One possible fix:
void List::deleteLowerThan(int n) {
Node* temp = head;
int tmpdata;
while(temp != nullptr) {
tmpdata = temp->data; // save the nodes data
temp = temp->next; // step before you delete
if(tmpdata < n) {
deleteFromList(tmpdata);
}
}
}

Unusual Segmentation Fault

I was trying to delete alternate nodes in a linklist. I observed a strange behaviour.
void delete_alternate_node_LinkedList(Node *head) {
Node *prev = head;
Node *curr = head->next;
while (prev != NULL and curr != NULL) {
prev->next = curr->next;
free(curr);
prev = prev->next;
if (prev != NULL) {
curr = prev->next;
}
}
}
This code works fine except the head being nullptr when I use free to delicate or intentionally keep a memory leak but if I change the line free(curr) with delete curr, I get a segmentation fault.
Can anyone explain me the reason?
Here are the boilerplate codes
class Node {
public:
int data;
Node * next;
Node(int data){
this -> data = data;
this -> next = NULL;
}
~Node() {
if(next) {
delete next;
}
}
};
Node* takeinput() {
int data;
cin >> data;
Node *head = NULL, *tail = NULL;
while(data != -1){
Node *newNode = new Node(data);
if(head == NULL) {
head = newNode;
tail = newNode;
}
else{
tail -> next = newNode;
tail = newNode;
}
cin >> data;
}
return head;
}
void print(Node *head) {
Node *temp = head;
while(temp != NULL) {
cout << temp -> data << " ";
temp = temp -> next;
}
cout << endl;
}
Your destructor has a problem
Let's assume
A->B->C->D->nullptr
Now when you delete B it invokes destructor (if you use free it won't).
it will delete recursively C (which in turn delete D) and ..... till the end
so in next iteration you are holding on to a dangling pointer (C) and getting the segfault when you are trying to derefence it.

How do I make my Linked List Print backwards in C++

How do I make my program print the Linked List backwards? I got the printForward function working fine but the printBackwards function just doesn't seem to do anything. I think I'm on the right track but I'm a little stuck right now. I think the while loop isn't running because temp is NULL for some reason.
Any help would be great.
Thanks
List.h
#include <iostream>
using namespace std;
class LinkedList
{
private:
struct Node
{
int data;
Node * next;
Node * prev;
};
Node * head, *tail;
public:
LinkedList();
bool addAtBeginning(int val);
bool remove(int val);
void printForward() const;
void printBackward() const;
};
#endif
List.cpp
#include "List.h"
LinkedList::LinkedList()
{
head = NULL;
tail = NULL;
}
bool LinkedList::addAtBeginning(int val)
{
Node* temp;
temp = new Node;
temp->data = val;
temp->next = head;
head = temp;
return false;
}
bool LinkedList::remove(int val)
{
return false;
}
void LinkedList::printForward() const
{
Node* temp = head;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
void LinkedList::printBackward() const
{
Node* temp = tail;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->prev;
}
cout << endl;
}
app.cpp
#include "list.h"
int main()
{
LinkedList aList;
aList.addAtBeginning(3);
aList.addAtBeginning(10);
aList.addAtBeginning(1);
aList.addAtBeginning(7);
aList.addAtBeginning(9);
aList.addAtBeginning(12);
aList.printForward();
aList.printBackward();
system("pause");
return 0;
}
I find it a bit odd that you only have an addAtBeginning method, and no method to add at the end, the latter which I would consider to be normal use of a linked list. That being said, I think the immediate problem here is that you never assign the tail to anything. Try this version of addAtBeginning:
bool LinkedList::addAtBeginning(int val)
{
Node* temp;
temp = new Node;
temp->data = val;
temp->next = head;
if (head != NULL)
{
head->prev = temp;
}
if (head == NULL)
{
tail = temp;
}
head = temp;
return false;
`}
The logic here is that for the first addition to an empty list, we assign the head and tail to the initial node. Then, in subsequent additions, we add a new element to the head of the list, and then assign both the next and prev pointers, to link the new node in both directions. This should allow you to iterate the list backwards, starting with the tail.
Update addAtBeginning function with given:
bool LinkedList::addAtBeginning(int val)
{
Node* temp;
temp = new Node;
temp->data = val;
temp->prev = temp->next = NULL;
// If adding first node, then head is NULL.
// Then, set Head and Tail to this new added node
if(head == NULL){
// If this linked list is circular
temp->next = temp->prev = temp;
head = tail = temp;
}else{ // If we already have at least one node in the list
// If this linked list is circular
temp->prev = head->prev;
temp->next = head;
head->prev = temp;
head = temp;
}
return false;
}
But remember, if you copy this function with the parts that it makes this list circular, you will get an infinite loop. So, either change print function or dont copy that parts.

Singly Linked List Infinite Loop

It's been a week since i started learning about linked list and i only managed to learn about singly linked list. So today i implemented the linked list which i learned in c++ and while i tried to run it the code goes into an infinite loop of some random numbers. I tried debugging the code but i coudn't find whats so ever is wrong with the code. The code is below. Help is appreciated.Thanks
#include <iostream>
using namespace std;
struct node{
int data;
node * next;
};
class singly{
private:
node * head,*tail;
public:
singly(){
head=NULL;
tail=NULL;
}
void createNode(int value){
node * temp = new node;
temp->data=value;
temp->next=NULL;
if(head==NULL){
head=temp;
tail=temp;
temp=NULL;
}
else{
tail->next=temp;
tail=temp;
}
}
void display(){
node * temp = new node;
head=temp;
while(temp!=NULL){
cout << temp->data << "\t" << endl;
temp->next=temp;
}
}
void insert_end(int value){
node*newnode = new node;
node*temp = new node;
newnode->data=value;
newnode->next=NULL;
temp=head;
while(temp->next!=NULL){
temp = temp->next;
}
temp->next=newnode;
}
void delete_node(){
node*current = new node;
node*previous = new node;
current = head;
while(current->next!=NULL){
previous=current;
current=current->next;
}
tail=previous;
previous->next=NULL;
delete current;
}
};
int main(){
singly lists;
lists.createNode(32);
lists.createNode(654);
lists.createNode(34);
lists.createNode(234);
cout<<"\n--------------------------------------------------\n";
cout<<"---------------Displaying All nodes---------------";
cout<<"\n--------------------------------------------------\n";
lists.display();
cout<<"\n--------------------------------------------------\n";
cout<<"-----------------Inserting At End-----------------";
cout<<"\n--------------------------------------------------\n";
lists.createNode(55);
lists.display();
cout<<"\n--------------------------------------------------\n";
cout<<"-----------------Deleing At End-------------------";
cout<<"\n--------------------------------------------------\n";
lists.delete_node();
lists.display();
}
The member function display does not make sense.
It overwtites the data member head with uninitialized newly created temp.
node * temp = new node;
head=temp;
so the function invokes undefined behavior.
The function can look like
void display()
{
for ( node * temp = head; temp != nullptr; temp = temp->next )
{
cout << temp->data << "\t";
}
}
Or it is better to define it the following way
std::ostream & display( std::ostream &os = std::cout )
{
for ( node * temp = head; temp != nullptr; temp = temp->next )
{
os << temp->data << "\t";
}
return os;
}
The data member insert_end is also wrong. It does not take into account that head and tail can be equalto nullptr and does not change them.
The function can be defined the following way
void insert_end(int value)
{
node *newnode = new node { value, nullptr };
if ( tail == nullptr )
{
head = tail = newnode;
}
else
{
tail = tail->next = newnode;
}
}
The member function delete_node firstly does not make sense for a singly-linked list and again is wrong and invokes undefined behavior. The function should remove the first node from the list.
Nevertheless if you want to remove the last node from the list then the function can look like
void delete_node()
{
if ( head != nullptr )
{
tail = nullptr;
node *current = head;
while ( current->next )
{
tail = current;
current = current->next;
}
if ( tail == nullptr )
{
head = tail;
}
else
{
tail->next = nullptr;
}
delete current;
}
}
For starters, display() is wrong. You want the update to be temp = temp->next; and it can also be initialized as node * temp = head hence not requiring the second line.
Your delete_node() can be re-written to:
if (head->next == NULL) // handles the case that it consists of 1 element
{
delete head;
head = NULL;
}
else
{
node *nextToEnd = head;
node *end = head->next;
while (end->next != NULL)
{
nextToEnd = end;
end = end->next;
}
delete end;
nextToEnd->next = NULL;
}
As stated in the comments, review the use of the new keyword

C++ Linked List: Memory Leak Issue

I'm trying to create a linked list that can append/delete/display items. I got the header and the test complete, and it seems to have worked. It successfully appended, deleted, and displayed the results. However, immediately after the results were displayed, I get a runtime pop-up saying "Debug Assertion Failed! Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)"
So I did some debugging, and obviously it's a memory leak (or at least I'm pretty sure it is). I swear my destructor was written correctly. My test works, the linked list works (plus it's member functions) works, so what am I doing wrong?
Here's my class declarations, default constructor, and destructor
template <typename T>
class Node
{
public:
T Value;
Node<T> *next;
Node(T nodeValue)
{
value = nodeValue;
next = NULL;
}
};
template <typename T>
class LinkedList
{
private:
Node<T> *head;
public:
LinkedList()
{ head = NULL; }
~LinkedList()
{
Node<T> *temp;
Node<T> *nextNode;
temp = head;
while (temp != NULL)
{
nextNode = temp->next;
delete temp;
temp = nextNode;
}
}
}
And here's the rest of the Linked List (even though it works but in case you ask)
void appendNode(T newValue)
{
Node<T> *newNode;
Node<T> *temp;
newNode = new Node<T>(newValue);
if (!head)
head = newNode;
else
{
temp = head;
while (temp->next)
temp = temp->next;
temp->next = newNode;
}
}
void deleteNode(T searchValue)
{
Node<T> *temp;
Node<T> *prev = NULL;
if (!head)
return;
if (head->value == searchValue)
{
temp = head->next;
delete head;
head = temp;
}
else
{
temp = head;
while (temp != NULL && temp->value != searchValue)
{
prev = temp;
temp = temp->next;
}
if (temp)
{
prev->next = temp->next;
delete temp;
}
}
}
void displayList() const
{
Node<T> *temp;
temp = head;
while (temp)
{
cout << temp->value << " ";
temp = temp->next;
}
}