This is simple adding nodes to linked list. I'm not able to figure out why the head pointer is being set to null with every call to add function.
//struct declaration of node
struct node {
int data;
node* next;
};
//adding node to the head pointer
void add_node(node* head, int d)
{
node* temp = new node;
temp->data = d;
temp->next = NULL;
node* tmp = head;
if (tmp != NULL) {
cout << "shal";
while (tmp->next != NULL)
tmp = tmp->next;
tmp->next = temp;
}
else {
//cout<<temp->data;
head = temp;
}
cout << "dh" << head->data;
}
int main()
{
node* head = NULL;
// calling the add function
add_node(head, 10);
// head is being taken as null here
add_node(head, 20);
}
Output:
dh10nulldh20null
Please help me in understanding where it went wrong.
I guess you didn't get what a pointer is.
void plus_one(int num) {
num += 1;
}
int main() {
int num = 42;
plus_one(num);
std::cout << num << std::endl;
}
Obviously, num is still 42. Why? Because in function plus_one you get num by copy.
When you call your add_node, you send a copy of your head pointer. Since it is a pointer, you can modify what is POINTED BY the pointer, NOT the pointer itself. What you do is the same thing as trying to get 43 with my example... It's not possible if you are getting a copy.
You need to pass the address of your pointer, so call your function as it : add_node(&head, 10); and write your prototype as it : void add_node(node** head,int d). You will have to modify your function to fit with your new node**.
Why does it work? Because you modify the content of the pointer which is POINTING TO you original pointer (which is POINTING TO your structure).
Related
This question already has answers here:
Reason to Pass a Pointer by Reference in C++?
(7 answers)
Closed 1 year ago.
I wrote this piece of code in C++ for the function Insert At Tail in a linked list but when the list is empty it is not inserting the data.
This is the picture of it:- https://i.stack.imgur.com/wKkXk.png
I don't know why the lines from 35 to 39 are not executed.
This is my code:-
#include <iostream>
using namespace std;
class node
{
public:
int data;
node *next;
// Constructor
node(int d)
{
data = d;
next = NULL;
}
};
void display(node *head)
{
if (head == NULL)
{
cout << "The list is empty !!" << endl;
}
while (head != NULL)
{
cout << head->data << "->";
head = head->next;
}
cout << endl;
}
void Insert_At_Tail(node *head, int data)
{
if (head == NULL)
{
head = new node(data);
return;
}
node *tail = head;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = new node(data);
return;
}
int main()
{
node *head = NULL;
int data;
cout << "Enter the data: ";
cin >> data;
Insert_At_Tail(head, data);
display(head);
return 0;
}
This is the snapshot of my output: https://i.stack.imgur.com/FFGj6.png
void Insert_At_Tail(node *head, int data)
In C++, by default function parametes are passed by value. This head parameter is a copy of the parameter that the caller passes in.
head = new node(data);
This sets the new head pointer. This is fine, but because this head is a copy of the original parameter, this does absolutely nothing, whatsoever, to the caller's passed-in head pointer. All this does is set the function's head parameter/variable. This has no effect on the head that was passed into this function.
You can do one of two things (your choice):
Pass the parameter by reference
return the new value of the head pointer from this function (which could be unchanged from what was passed in, if there were no changes to the head pointer), and have the caller make save the new head pointer.
The problem is that you don't change head at the caller. Either take a reference to the head
void insert_at_tail(node*& head, int data)
or better, return the new head:
void insert_at_tail(node *head, int data) {
if (!head) return new node(data);
node *tail = head;
while (tail->next != NULL) tail = tail->next;
tail->next = new node(data);
return head;
}
called like such:
head = insert_at_tail(head, data);
Even better is to wrap the whole thing into a class so you can write linked_list.insert_at_tail(data) and only have to mutate its members.
I am currently learning some C++ for a course I am taking in school. I have basic understanding of lvalues and rvalues, but I am unable to determine why I am receiving a compiler error.
I am creating a singly linked list and need to be able to reverse it. As per my assignment I have two classes. The first is the node and just holds an int as well as a pointer.
class Node {
int data;
Node *next;
public:
//Constructor
Node(int d) {
data = d;
next = NULL;}
//Set to next Node
void SetNext(Node *nextOne) {
next = nextOne;}
//Returns data value
int Data(){return data;}
//Returns next Node
Node *Next() {return next;}
};
Then I have a linked list class that has a header pointer and then a number of functions for adding, printing etc. the list.
class LinkedList {
Node *head;
public:
//Constructor
LinkedList(){head = NULL;}
void AddNode(int d) {
//Create a new Node
Node *newNode = new Node(d);
//Create a temporary pointer
Node *temp = head;
//If there are already nodes in the list
if(temp != NULL) {
//Parse through to the end of the list
while(temp->Next() != NULL) {
temp = temp->Next();}
//Point the last Node in the list to the new Node
temp->SetNext(newNode);
}
//If adding as the first Node
else{
head = newNode;}
}
void PrintList() {
//Temporary pointer
Node *temp = head;
//If there are no nodes in the list
if(temp == NULL) {
std::cout << "The list is empty" << std::endl;}
//If there is only one node in the list
if(temp->Next() == NULL) {
std::cout << temp->Data() << std::endl;}
//Parse through the list and print
else {
do {
std::cout << temp->Data();
temp = temp->Next();
}
while(temp != NULL);
}
}
//Returns the number of nodes in the list
int CountList() {
//Temporary pointer
Node *temp = head;
//Counter variable
int counter = 0;
//If the list is empty
if(temp == NULL) {
return counter;}
//Parse through Nodes counting them
else {
do {counter++;
temp = temp->Next();
}
while(temp != NULL);
}
return counter;
}
//Reverses the list
Node *ReverseList() {
//Initially set to NULL then tracks the new head
Node *marker = NULL;
//Tracks the next one in the list
Node *nextOne;
//Sets the first Node to NULL and then sets the last Node to point to
//the first one and rotates through the list pointing the last to the
//first
while(head != NULL) {
nextOne = head->Next();
head->Next() = marker;
marker = head;
head = nextOne;
}
//Setting the head back to the start again
head = marker;
}
};
One of those functions is supposed to reverse the list. The line "head->Next() = marker;" in the ReverseList function is causing a "lvalue required as left operand of assignment" error when compiling.
Any insight as to why this is occurring and how I can correct the problem?
Thank you in advance!
The return from the call to Next() is an rvalue. As you are in a class function, you don't need to call the Next function to get at the private next pointer, you can just use it directly.
head->next = marker;
Your Next() function returns a pointer, and you then do this:
head->Next() = marker;
You're changing the pointer to marker and not what it's pointing at. To solve this you need to dereference that pointer:
*head->Next() = marker;
your signature for next is:
Node *Next() {return next;}
This makes a copy of next pointer at return and hence it is treated as r-value and not l-value.
One way of overcoming this would be to use a pointer-to-pointer:.
Node **Next() {return &next;}
And then use it as:
int main()
{
Node* marker=new Node(89);
Node* nod=new Node(9);
*(nod->Next())= marker;
cout<<(nod->next)->data<<endl;
cout << "Hello World" << endl;
return 0;
}
This makes it more complicated to use.
I have the following function to reverse a linked list:
Node* reverseUtil(Node *head, Node *prev) {
if (head->next == NULL) {
head->next = prev;
return head;
}
Node *next = head->next;
head->next = prev;
prev = head;
head = next;
return reverseUtil(head, prev);
}
When I call this with Node* head = reverseUtil(head, NULL); it works fine and ultimately returns the head of the reversed linked list. Example for 1->2->3, it returns head with 3->2->1.
However, when I modify it to the following, the resultant head pointer only has the last node of the reversed linked list (originally the starting point of the list. Example: for original list 1->2->3, head at the end only has 1.
void reverseUtil(Node *head, Node *prev) {
if (head->next == NULL) {
head->next = prev;
return;
}
Node *next = head->next;
head->next = prev;
prev = head;
head = next; //head pointer should update here on forward path. This seems to be happening.
reverseUtil(head, prev);//after this step returns, head should stick to the last updated point and should return unchanged but this does not happen.
}
I think I am missing something basic here. I would expect that the statement head = next at each call of the function would update the head pointer. It should ultimately point to the new beginning of the reversed linked list and should remain unchanged as the recursive calls return. However it seems to be continuously getting updated on the return path.
When you pass a pointer to a function like void foo(type* bar) the address that the pointer contains is passed by value. If you need to change that address then you need to pass it by reference like void foo(type *&bar). I think that you are confused by the fact that this works
void foo(int * bar) { *bar = 10; }
int man()
{
int x = 5;
foo(&x);
// x is now 10 here
}
Here we are not changing what the pointer points to but we are changing the value of the pointed to object. We can see that changing the address of the pointer has no affect when not passed by reference with:
void foo(int * bar)
{
int foobar = 10;
bar = &foobar;
}
int main()
{
int x = 5;
foo(&x);
std::cout << x;
}
Live Example
I am a beginner in C++ and need help in many things. Well, for the starters, I have been working on Linked List and not really getting why my header(the first pointer which points towards first node) keep on rotating. I am just pointing it towards first node plus my display node is just displaying last node, why is it so?. Please tell me where I am wrong. Thank you in advance
#include <iostream>
#include <conio.h>
using namespace std;
struct Node
{
int data;
Node *link;
};
Node* create_Node()
{
int no_of_nodes;
Node *header = new Node;
Node *ptr = new Node;
header = ptr;
cout << "Enter no of nodes:";
cin >> no_of_nodes;
cout << "Enter data:";
for(int n = 0; n < no_of_nodes; n++)
{
cin >> ptr->data;
Node *temp = new Node;
ptr->link = temp;
temp = ptr;
}
ptr->link = NULL;
return ptr;
}
void display_link_list(Node * list)
{
Node *temp = new Node;
temp = list;
while(temp != NULL)
{
if(temp->link != NULL)
{
cout << "List:" << list->data << endl;
temp = temp->link;
}
}
}
int main()
{
Node *n = new Node;
n = create_Node();
display_link_list(n);
getch();
return 0;
}
Welcome to C++. My advice here is to break the Linked list into two. First the Nodes and then a List struct.
struct Node
{
int data;
Node *next;
Node(int data) : data(data), next(NULL) {}
};
struct List {
Node* tail;
Node* head;
List() : head(NULL), tail(NULL) {}
void insert(int data) {
if(head==NULL) {
head = new Node(data);
tail = head;
} else {
tail->next = new Node(data);
tail = tail->next;
}
}
};
Now you can insert one element into the list at a time and use head to print the list from beginning to end.
Something basic that you need to understand:
When you do Node* p = new Node, you are setting variable p to point to the start address of a piece of memory, the size of which being equal to sizeof(Node).
Now, when you then do p = something else (which often appears in your code), you are essentially overriding the previous value of p with some other value. It is like doing:
int i = 5;
i = 6;
So your code does not do what you're expecting to begin with.
In addition to that, what's bad about overriding the first value with a second value in this case, is the fact that the first value is the address of a dynamically-allocated piece of memory, that you will need to delete at a later point in your program. And once you've used p to store a different value, you no longer "remember" that address, hence you cannot delete that piece of memory.
So you should start by fixing this problem in each of the following places:
Node *header = new Node; // Variable 'header' is assigned
header = ptr; // Variable 'header' is reassigned
Node *temp = new Node; // Variable 'temp' is assigned
temp = list; // Variable 'temp' is reassigned
Node *n = new Node; // Variable 'n' is assigned
n = create_Node(); // Variable 'n' is reassigned
I got some problem with the linked list I've written. I dunno if it's either my insert function that the problem, or if it's my traverse function that's not correct. I hope for some input. A side note, I'm initalising the list in main now since I don't know if my initNode function is correct.
#include <iostream>
using namespace std;
typedef struct Node
{
int data;
Node *next;
};
void initNode(Node *head)
{
head = new Node;
head->next = NULL;
}
void insertNode(Node *head, int x)
{
Node *temp;
temp = new Node;
temp->data = x;
temp->next = head;
head = temp;
}
void traverse(Node *head)
{
Node *temp;
temp = head;
if(head == NULL)
{
cout << "End of list. " << endl;
}
else
{
while(temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
}
}
int main()
{
Node *head;
head = NULL;
insertNode(head, 5);
insertNode(head, 5);
traverse(head);
return 0;
}
Your head isn't being returned to main from insertNode. Note that even though head is a pointer, the pointer itself is a value and any changes to the pointer value are not reflected in main. The simplest solution is to pass back the updated value of head:
Node *insertNode(Node *head, int x)
{
...
return head;
}
And update it in main:
head = insertNode(head, 5);
The other common way of doing this is to pass a pointer to a pointer and update it directly:
void insertNode(Node **head, int x)
{
Node *temp;
temp = new Node;
temp->data = x;
temp->next = *head;
*head = temp;
}
And call it like this:
insertNode(&head, 5);
The way you have you initNode function written will result in memory leaks. You've passed in a pointer, but you need to pass in a reference to a pointer. (Same issue that James and casablanca mentioned for insertNode.)