Here are both of My Codes. One Using structure and Another Using Pointer to Structure. But when I am not using a Pointer it's not working. Al though I think they are same. But I am still a beginner. So I need to understand what's going wrong.
Not Working Code:
struct Node{
int data;
struct Node* next;
};
void insert(struct Node** head_ref,int data){
//Not Working Here. The Header should change after every insert but it isn't Moving from it's Memory;
struct Node temp ;
temp.data = data;
temp.next = (*head_ref);
(*head_ref) = &temp;
}
int main(){
struct Node *head = NULL;
insert(&head,4);
insert(&head,2);
insert(&head,11);
insert(&head,9);
while(head->next !=0 ){
std::cout << head->data <<" ";
head = head->next;
}
return 0;
}
Working Code:
struct Node{
int data;
struct Node* next;
};
void insert(struct Node** head_ref,int data){
//The Problem is in This Line. Pointer to Structure is Working But only Structure isn't
struct Node* temp = (struct Node*) malloc(sizeof(struct Node)) ;
temp->data = data;
temp->next = (*head_ref);
(*head_ref) = temp;
}
int main(){
struct Node *head = NULL;
insert(&head,4);
insert(&head,2);
insert(&head,11);
insert(&head,9);
while(head->next !=0 ){
std::cout << head->data <<" ";
head = head->next;
}
return 0;
}
With the code struct Node temp ; ... (*head_ref) = &temp;, you store the address of a local variable. As soon as function insert has finished, the lifetime of the object stored in this variable ends, and accessing the pointer after this time is undefined behaviour.
This is different from your second case, where struct Node* temp = (struct Node*) malloc(sizeof(struct Node)) allocates an object dynamically; the lifetime of such an object ends when it is deleted explicitly, such that you may then refer to its address.
It is the difference between the heap and stack What and where are the stack and heap?
void insert(struct Node** head_ref,int data){
//Not Working Here. The Header should change after every insert but it isn't Moving from it's Memory;
struct Node temp ;
temp.data = data;
temp.next = (*head_ref);
(*head_ref) = &temp;
}
In the original code, temp is located on stack, since got destroyed automatically at the end of the scope
void insert(struct Node** head_ref,int data){
//The Problem is in This Line. Pointer to Structure is Working But only Structure isn't
struct Node* temp = (struct Node*) malloc(sizeof(struct Node)) ;
temp->data = data;
temp->next = (*head_ref);
(*head_ref) = temp;
}
This could work because it is located on heap, thus you have to manually delete it when you finish using it
Related
#include<iostream>
#define print(x) std::cout<<x<<std::endl;
class Node
{
public:
int data;
Node* next;
};
class LinkedList
{
private:
Node** head_ref;
public:
LinkedList() :head_ref(NULL) {};
void insertFront(int new_data)
{
Node* new_node = new Node();
new_node->data = new_data;
if(this->head_ref == NULL)
this->head_ref = &new_node;
else
{
new_node->next = *(this->head_ref);
this->head_ref = &new_node;
}
}
void PrintLinkedList()
{
Node* temp = (*(this->head_ref));
while (temp->next != NULL)
{
print(temp->data);
}
print("\n");
}
};
int main()
{
LinkedList a1;
a1.insertFront(5);
a1.insertFront(6);
a1.insertFront(7);
a1.PrintLinkedList();
std::cin.get();
}
As you will see in the screenshots in the watch1 tab the this->head_ref preserves the location of the Node* but Node* i.e. (*(this->head_ref)) doesn't preserve the location of the Node. I want to know what is causing this. Is it because Node** head_ref has no regulation in how the inside pointer points to the Node or is it a scope problem? The problem occurs each time right after the next function call happens and the debugger enters the insertFront function, the Node* becomes a free pointer pointing to nothing.
First call screenshot
Second call screenshot before entering insertFront
Second call screenshot just after entering insertFront but a new Node object has not been made yet
The answer is provided by #IgorTandetnik in the comments.
The Node object is allocated on the heap. But the Node* object named new_node is allocated on the stack. You have head_ref point to new_node and new_node point to the Node object. Then the function returns, new_node is gone, and there is no longer any connection between head_ref and the heap-allocated Node. head_ref points to some garbage value where new_node used to be, and Node on the heap is leaked as nothing points to it anymore.
I have changed the code accordingly by using Node* head_ref which will refer to a heap allocated Node instead of the new_nodepointer which goes out of scope.
#include<iostream>
#define print(x) std::cout<<x<<std::endl;
class Node
{
public:
int data;
Node* next;
};
class LinkedList
{
private:
Node* head_ref;
public:
LinkedList() :head_ref(NULL) {};
void insertFront(int new_data)
{
Node* new_node = new Node();
new_node->data = new_data;
if(this->head_ref == NULL)
this->head_ref = new_node;
else
{
new_node->next = this->head_ref;
this->head_ref = new_node;
}
}
void PrintLinkedList()
{
Node* temp = this->head_ref;
while (temp->next != NULL)
{
print(temp->data);
temp = temp->next;
}
print(temp->data);
print("\n");
}
};
int main()
{
LinkedList a1;
a1.insertFront(5);
a1.insertFront(6);
a1.insertFront(7);
a1.PrintLinkedList();
std::cin.get();
}
struct Node
{
int data;
struct Node *next;
};
Node *AppendNode(Node *head, int data) {
Node *ptr = head;
struct Node node = {data, ptr->next};
head->next = &node;
return head;
}
void PrintNode(Node *head) {
Node *ptr = head;
while (ptr != 0) {
printf("%d ", ptr->data);
ptr = ptr->next;
}
}
int main() {
Node node = {1 , 0};
Node* head = &node;
head = AppendNode(head, 2);
PrintNode(head);
return 0;
}
Output is (1,3830) instead of (1,2). Check debuggers I saw node value changes from 2 to 3830 in this step ptr = ptr->next; inside PrintNode. Sorry I am new to C++.
This is wrong:
Node *AppendNode(Node *head, int data) {
Node *ptr = head;
struct Node node = {data, ptr->next};
head->next = &node;
return head;
}
You are inserting a pointer to a local stack variable into your linked list. As soon as your function returns, the memory referenced by &node is going to be clobbered pretty soon.
Also, whatever head->next was previously pointing to before the assignment is getting leaked (and lost).
Better:
Node* AppendNode(Node *head, int data)
{
Node* newNode = new Node;
newNode->data = data;
newNode->next = head;
head = newNode;
return head;
}
But technically the above is "prepending" to the list, not "appending" as your function signature suggests. Maybe that's what you want, but if not, that's an exercise I'll leave up to you. :)
As the other answer from Bo mentions, don't forget to call "delete" on your nodes when you are done with the list to avoid the memory leak.
You have a local Node in AppendNode. As soon as you leave the function, that node is gone.
If you must create nodes dynamically, you do that with new Node. Just don't forget to delete the nodes later.
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
#include <iostream>
using namespace std;
struct Node
{
int item; // storage for the node's item
Node* next; // pointer to the next node
};
Node* addNode(Node*& head, int data , int& count)
{
Node * q; // new node
q = new Node; // allocate memory for the new mode
q->item = data; // inserting data for the new node
q->next = head; // point to previous node ?? how would i do that? ( am i doing it correctly?)
count++; // keep track of number of node
head = q;
return q;
}
int main()
{
int a, count=0;
int data;
bool repeat;
Node *head= NULL;
//^^ assuming thats creating the first node ^^
do
{
cout << "please enter the data for the next node" <<endl;
cin >> data;
addNode(head, data, count);
cout << "do you wish to enter another node? (enter true or false)" << endl;
cin >>repeat;
}
while (repeat == true);
// assuming this is the print function
while(head != NULL)
{
cout << "output" << temp->item << endl;
cout << temp->next << endl;
}
system("pause");
return 0;
}
okey i tried adding a new element in the list how would i move the head around like a LIFO memory (stack) so the last element is on the very top..
any help would be appreciated ! The pointers and the nodes are messing with my brain lately ....
temp is an uninitialized pointer. So -
temp-> item = a; // temp is not initialized or pointing to a memory location
// that has Node object to use operator ->
First, temp needs to be allocated memory location using new.
temp = new Node;
temp -> item = a;
And now assign it head. Similarly allocate memory for the child nodes too in the while loop. And return all the resources acquired from child to head using delete before program termination.
You seem to have some misunderstandings here:
Your "head" is the start of the list. It's always the start.
You add append elements to a linked list by assigning them to the last node's next pointer.
Third, you're not allocating anything.
Node *head= new Node();
Node *temp = new Node();
cout<<"enter something into data"<<endl;
cin >> a ;
temp->item = a;
head->next = temp;
Now ... to add the next thing, you either need to keep track of the last node (tail), or traverse the list to find the last node.
Node *nextNode = new Node();
nextNode->item = 0.0;
Node *i;
for (i = head; i->next != null; i = i->next);
i->next = nextNode;
This is O(n) execution time. By keeping track of the tail you make it O(1):
Node *head= new Node();
Node *tail = head;
Node *temp = new Node();
cout<<"enter something into data"<<endl;
cin >> a ;
temp->item = a;
tail->next = temp;
tail = temp;
Node *nextNode = new Node();
nextNode->item = 0.0;
tail->next = nextNode;
tail = nextNode;
EDIT: As pointed out, if you want to prepend to the list, you would:
temp->next = head;
head = temp;
Since I'm not sure every answer completely answers it, here's a linked list implementation (written without testig:
// your (correct) structure
struct Node
{
float item; // storage for the node's item
Node* next; // pointer to the next node
};
Now we need two pointers somewhere to look after the list:
/* some pointers */
struct List
{
Node* head;
Node* tail;
};
Now we need to create some elements. As others have said, you can do that with new:
/* create some elements we want to link in */
Node* elem1 = new Node();
Node* elem2 = new Node();
Node* elem3 = new Node();
/* maybe even set their properties! */
elem1->item = 3.14;
elem2->item = 3.14;
elem3->item = 3.14;
Notice how I didn't try to add these elements to a list yet? That's because I've got a function in mind which looks like this:
void addtolist(List &list, Node* node)
{
/* if no head, initialise the list */
if ( list->head == NULL )
{
list->head = node;
list->tail = node;
}
else if ( list->head != NULL && list->tail != NULL )
{
/* access the tail element and set its
next to this ptr.
Move tail to this node */
list->tail->next = node;
list->tail = node;
}
else
{
/* probably raise an exception! */
}
}
You can call this by doing this:
List l;
addtolist(l, elem1); /* etc */
Deleting elements is somewhat more tricky, since you have to go to that element, remember its previous element, grab it's next element, join them up and delete the Node* you're on.
Now for traversing lists... your terminology HEAD|TAIL reminds me of Erlang and tail recursion, where the current element is referred to as the head and the remainder the tail. If I write:
Node* cur = l.head;
while ( cur != NULL )
{
// do something with cur.item ?
cur = cur->next;
}
You can see this happening. Replacing cur with head here would be harmless thanks to the List struct.
Finally, I've used a very C-like approach here, but there's scope for templates:
template<typename T>
struct node
{
T item; // storage for the node's item
Node<T>* next; // pointer to the next node
};
and encapsulating the List struct as a class:
template<typename T>
class List
{
protected:
Node<T>* head;
Node<T>* tail;
public:
void addtolist(Node<T>* node);
Node<T>* gethead();
Node<T>* gettail();
}
Which brings you a little bit closer to std::list.
Additionally note that you are doing an implicit cast from int to float on
temp-> item = a;
as a is an int, while temp->item is a double.
To solve your problem: You want to allocate a new structure before accessing temp, thus
temp = new Node();
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.)