Dereferencing head of empty linked list for next node - c++

I was trying to implement linked list in C++, when this idea struck my mind. With standard node definition as
class node {
public:
int data;
node *next;
};
I created an empty list node *head; then tried this
if(head->next == nullptr)
cout<<"Stores nullptr";
if(! head->next)
cout<<"Returns bool values";
But there is no output, so what is stored inside head->next ?

First of all, you should create some space/allocate memory for the node class in main.
Note that
node *head; is only a declaration not a definition. For further details have a look at What is the difference between a definition and a declaration?.
You allocate space for the object
Initialize its values, to be more elegant define a constructor method
node *head = new node;
head->next = nullptr;
head->data=0;
I would still consider this as a duplicate of Linked lists in C++

If you declare node *head;, head is an uninitialized pointer that contains a random address. Dereferencing it is Undefined Behavior?
You need to a) initialize head: node *head = nullptr;, and b) test for that condition: if (head == nullptr) { head = new node; node->head = nullptr; ...

Related

How to create a node using the structure definition if the integer value is passed to a function?

The Definition of the structure is as follows.
//Structure of the linked list node is as follows:
struct Node {
int data;
struct Node* next;
Node(int x) {
data = x;
next = NULL;
}
};
I have to complete this function which I have completed this way. I am trying to create a Node using the newData parameter passed in the function definition. But it shows the error which I have attached below.
// function inserts the data in front of the list
Node* insertAtBegining(Node *head, int newData) {
//Your code here
struct Node* newNode(newData);
struct Node* temp;
temp=head;
head=newNode;
newNode->next=temp;
}
I get this error while I am create a node by passing newData as parameter to struct Node *newNode(newData);
In function Node* insertAtBegining(Node*, int):
prog.cpp:67:32: error: invalid conversion from int to Node* [-fpermissive]
struct Node *newNode(newData);
Thank You for your help.
Your constructor returns a Node, not a Node*, so when you try to initialize newNode, the compiler thinks you're trying to create a pointer using an int. Instead you should be expecting your constructor to give you a Node:
Node newNode(newData);
Your insertAtBegining() implementation needs to create a new Node object. You aren't doing that. Right after your teacher's Your code here comment, your attempt has defined a "Node pointer" variable (whose type is Node*), but your attempt hasn't initialized that to any Node object (data that would have been passed to an object's constructor isn't the same as the object itself).
Also, you don't need to keep repeating struct that way that us old guys used to do with old-fashioned C code.
Lastly, you seem to also want to return the list's new head node back to the function's caller, but are unclear how you want to achieve that. There are two ways. The way that your code seems to be leaning towards is returning the new head in the same head parameter. In that case, it should look like this:
void insertAtBegining(Node** head, int newData)
{
//Your code here
Node* newNode = new Node(newData);
Node* temp;
temp = *head;
*head = newNode;
newNode->next = temp;
}
(The head parameter could also have been a "reference to a Node*", instead of this "pointer to a Node*", by making appropriate changes to the code.)
The second option (which maintains your teacher's recommended function signature) is to return the new head via the function's return value:
Node* insertAtBegining(Node* head, int newData)
{
//Your code here
Node* newNode = new Node(newData);
newNode->next = head;
return newNode;
}

Program is crashing from creating push function for Linked List

I am trying to implement a stack using a Linked List. My program keeps crashing and when trying to print the new Linked List, it prints an unsigned integer. My print function works fine, so it is this function below.
Please help.
void LinkedList::Push (int val)
{
Node* newHead = new Node;
Node* oldHead = new Node;
newHead->value = val;
oldHead = head;
head = newHead;
oldHead->prev = head;
head->next = oldHead;
delete newHead;
}
One issue is that the Node that you've newed in the definition of oldHead is never deleted. Since you set oldHead to head immediately after creating it, I would suggest this as your definition:
Node* oldHead = head;
The main issue, though, is that you delete newHead, which is now what head points to. Therefore, when you go to print head, you are reading invalid data.
I would highly recommend leaving the resource handling to objects like std::shared_ptr instead of newing and deleteing yourself.
I'm not sure I understood your question.
Your fixed method:
void Push( const int val )
{
Node* newNode { new Node };
newNode->value = val;
newNode->next = head;
head = newNode;
}
Read more about Linked List operations here. You do not need a doubly linked list to implement a stack - you only need to push/pop at one end.
[EDIT]
I didn't notice you are using a doubly linked list (this is why a complete/verifiable example is required). As I said, for a stack implementation, a singly linked list is enough.

c++ constructor seems to return pointer to the same object every time [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 5 years ago.
I have a simple implementation of a Linked list class, which has pointers to Node objects which I have also defined.
The function insertHead creates a new Node and inserts it at the head.
However, whenever I call the function, the constructor seems to return a pointer to the same object every time. (I checked that using GDB)
I am pasting snippets of the code here. Can someone please let me know if something seems off?
void LinkedList::insertHead(int val){
Node temp(val);
if(head == NULL){
head = tail = &temp;
} else {
temp.setNext(head);
head = &temp;
}
}
Class definitions:
class LinkedList{
Node *head;
Node *tail;
...
class Node{
int val;
Node *next;
...
Node::Node(int x){
val = x;
next = NULL;
}
You cant assign address of automatic storage variable and use it out of the body, becouse it got out of scope (undefined behaviour). You need to dynamically allocate space on heap for the node.
Node * temp = new Node(val);
if(head == NULL)
{
head = tail = temp;
} else {
temp.setNext(head);
head = temp;
}
And in destructor free all nodes.
You need to allocate your nodes on heap rather than stack. (I encourage you to read about those two). Also please use nullptr instead of NULL if supported ( > c++11)
void LinkedList::insertHead(int val){
Node* temp = new Node(val);
if(head == nullptr){
head = tail = temp;
} else {
temp->setNext(head);
head = temp;
}
}
This will also require you clean up the nodes properly using the delete to avoid memory leaks which will most probably require adding a custom destructor to your list class, something along those lines:
LinkedList::~LinkedList() {
Node* node = head;
while(node != nullptr) {
Node* toDel = node;
node = node->next;
delete toDel;
}
}

create a doubly linked list in C++

I'm creating a programme that needs to read data from a spreadsheet in CSV form and assigns it to a doubly linked list in C++.I have created a singly linked list but I'm at a loss as to how to use this idea to make a doubly linked list. I understand you require a previous pointer but I am unsure as to actually implementing the code.
code for my singly linked list:
to add to the list:
if (!m_head)
{
m_head = new Node(name, reference,latitude,longitude);
}
else
{
Node *current = m_head;
while (current->getNext() != 0)
{
current = current->getNext();
}
current->setNext(new Node(name, reference,latitude,longitude));
}
please note: Node is a separate class to store data about the node e.g. name.
Each List Node must a have a pointer to the previous and to the next List Node.
The List is then the container of List Nodes , linked together as a chain.
struct ListNode;
typedef struct ListNode {
struct ListNode *next;
struct ListNode *prev;
void *value;
} ListNode;
typedef struct List {
int count;
ListNode *first;
ListNode *last;
} List;
You need then to implement the methods push and pop accordingly.
The tricky part is the remove method. Store the two pointers of the previous and next Node that you want to delete, and then assign them accordingly to the previous and following node:
ListNode *after = node->next;
ListNode *before = node->prev;
after->prev = before;
before->next = after;
This article may help you, full code and explanation
http://c.learncodethehardway.org/book/ex32.html

Linked list, add node to end

I'm working on a project and I was given this function to complete
void addToEnd(node*& head, string newVal)
Effect: adds new node to tail end of list
Precondition: head is a pointer to first node in the list (list MAY be empty)
Postcondition: list contains one more node
My question is what is the string newVal for?
The value_type of this class is of type DOUBLE so I'm confused what string newVal is for. So I can't set the newVal in the node because it is of two different types.
This is what I have so far. I'm not sure if im going in the right direction.
node *temp = new node;
temp = head;
while(temp->link() != NULL){
temp = temp->link();
}
head->set_link(temp);
I'm not even sure where to use the string in this block of code.
link() returns the member variable node* link_field
set_link() sets the new link to the link_field
Well, we're guessing that they somehow expect you to turn a string into a double with a function like std::stod.
As for your list manipulation code, there's a few problems:
node *temp = new node;
temp = head;
This creates a new node, puts its pointer in temp, then immediately overwrites temp with head, losing (leaking) the new node. Don't do that.
while(temp->link() != NULL){
temp = temp->link();
}
This is close, but might not work. The problem is that you need to keep track of the real node pointer, not a copy.
Normally, in a linked list API using pointers instead of references, the "add node" function looks like:
void addToEnd(node** head, string newVal)
{
while(*head)
head = &((*head)->next);
*head = new node;
(*head)->value = newVal;
(*head)->next = 0;
}
Note that if the list is empty, the passed-in head pointer is altered to point to the new node. If the list is not empty, the last next pointer is altered instead.
The API you're given (i.e. the link and set_link methods) doesn't allow this, because the head pointer is not a node and those functions require a node. So you've got to do it a little differently, namely you have to handle the empty list case separately.
void addToEnd(node*& head, string newVal)
{
// Create the node.
node* newNode = new node;
newNode->value = std::stod(newVal);
newNode->set_link(0);
if(!head) // Empty list?
{
head = newNode;
return;
}
// Find last node.
node* item = head;
while(item->link())
item = item->link();
item->set_link(newNode);
}