Linked List - pointers - c++

I created a linked list and when I tried to print values of the nodes and used NULL as a bound, it didn't work. For example:
#include <iostream>
typedef struct Node;
typedef Node* Node_ptr;
struct Node
{
int i;
Node_ptr next;
};
int main()
{
Node_ptr ptr, head;
ptr = new Node;
head = ptr;
// load
for(int j = 0; j < 4; j++)
{
ptr->next = new Node;
ptr->i = j;
ptr = ptr->next;
}
// print
ptr = head;
while(ptr->next != NULL)
{
std::cout << "print: " << ptr->i << std::endl;
ptr = ptr->next;
}
}
However, when I run this code, the code gets stuck in an endless loop in the while loop.
It never understands that the linked list is only 5 nodes long, it just keeps on going. I can't understand why that happens.

You probably just need to initialize your pointers (to NULL), otherwise they'll just contain garbage, and will thus also appear as being valid pointers.
For instance:
for(j = 0; j < 4; j++)
{
ptr->next = new Node;
(ptr->next)->next = NULL;
ptr->i = j;
ptr = ptr->next;
}

Try value initializing your Node:
ptr = new Node();
instead of
ptr = new Node;
Otherwise, you'll just have garbage in the members.

while(ptr->next != NULL)
You clearly coded it to continue until ptr->next is NULL. Maybe you should set ptr->next to NULL for at least one item in the list? This is why it is common in C to memset(&object, 0, sizeof(object));, or in C++ to have a constructor.
typedef struct Node
{
int i;
Node* next;
Node() : i(0), next(NULL) {} //prevents this problem
}

Related

cannot append to LinkedList implementation

I sketched up this small single linked list example. But for some reason, new node do not get appended to the list correctly.
Can someone help me by detecting the error please?
struct Node {
Node(int x, Node *next = nullptr) : x{x}, next{next} {}
int x;
std::shared_ptr<Node> next;
};
class LinkedList {
public:
LinkedList(std::vector<int> const &v) {
for (auto i = 0; i < std::size(v); ++i) {
auto temp = std::make_shared<Node>(v[i], nullptr);
if (head == nullptr) {
head = temp;
} else {
auto ptr = head;
while (ptr != nullptr) {
ptr = ptr->next;
}
ptr = temp;
}
}
}
std::shared_ptr<Node> head = nullptr;
};
int main() {
auto v = std::vector<int>{1, 2, 3};
auto l = LinkedList{v};
}
Think about what ptr is when you assign it to temp.
It is a local variable that you initialized with the link list's head member before the while loop. When you assign temp to it, you know its value is the nullptr, okay. So you have assigned a pointer to a new node to a local variable that currently holds a nullptr. How is that going to add an item to your linked list?
To insert an item into the list you need a pointer to a node in the list and assign a pointer to its next member e.g.
...
auto ptr = head;
while (ptr->next != nullptr) {
ptr = ptr->next;
}
ptr->next = temp;
...
But as mentioned in comments of this answer, the way you are inserting each item has O(n) running time as you need to iterate through the entire list to find the end. The correct way to do this would be for each insert to be O(1).

Inserting an element at the tail of linked list

I am new to data structures. I finally got the hang of adding new element at the beginning of linked list
but now there is another problem. I have watched so many YouTube videos yet the problem isn't solved. I am trying to add an element at the end of this linked list but when I do the first two elements disappear. Please help!
#include <iostream>
using namespace std;
class Node{
public:
int data;
Node *next;
Node(){
data = 0;
next = NULL;
}
};
Node* add_end(Node* a, int new_data){
Node* ptr, *temp;
ptr = a;
temp = new Node();
temp->data = new_data;
temp->next = NULL;
while(ptr->next != NULL) {
ptr = ptr->next;
}
ptr->next = temp;
return ptr;
}
void print(Node* a){
while(a != NULL){
cout << a->data << " ";
a = a->next;
}
}
int main(){
Node *head = NULL;
Node *second = NULL;
Node *third = NULL;
head = new Node();
second = new Node();
third = new Node();
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = NULL;
cout << "Before Adding:\n";
print(head);
head = add_end(head, 4);
cout << "\nAfter Adding: \n";
print(head);
return 0;
}
The function add_end should return the pointer to the head node.
Your current implementation returns the pointer to the second last node, which is calculated in the process of adding element.
You should return a instead of ptr from the function add_end.
Also you should return temp before the loop when ptr is NULL, or NULL will be dereferenced and it may lead to runtime error.

Why does my code stop running when it comes to pointers?

I need to make a simple program with linked lists but my code just stops running.
Down below are to codes, first is the main .cpp file, and the second is header where the problematic function is defined. The code stops when it comes to assigning "new_" pointer attributes (marked with arrows). The function, as its name says, need to generate a linked list from an array, and return the head of that list.
I am using dev c++ for compiling, and he is not throwing any error or warning.
<main.cpp>
#include<stdio.h>
#include"LinkedList2.h"
int main(){
node *head;
int A[] = {2,8,12,9,7};
int n = sizeof(A) / sizeof(A[0]);
head = CreateListFromArray(A, n);
PrintList(head);
return 0;
}
<LinkedList2.h>
#include<stdio.h>
typedef struct node_{
int x;
struct node_ *next;
}node;
node* CreateListFromArray(int A[], int n){
node *head = NULL, *tmp = head, *new_;
for(int i = 0; i < n; i++){
new_->next = NULL; // <------
new_->x = A[I]; // <------
tmp->next = new_;
tmp = tmp->next;
}
return head;
}
void PrintList(node *head){
for(node *tmp = head; tmp != NULL; tmp = tmp->next) printf("%d ", tmp->x);
}
you need to allocate memory for each new node
node* CreateListFromArray(int A[], int n){
node *head = NULL, *tmp = head;
for(int i = 0; i < n; i++){
node *new_ = new node():
new_->next = NULL; // <------
new_->x = A[I]; // <------
tmp->next = new_;
tmp = tmp->next;
}
return head;
}
you also dont have a valid head pointer either, i leave that for you to sort out
note in c++ you dont need typedef any more.
you also have to change A[I] to A[i], because I doesn't exist

singly linked list c++ constructor, destructor and printing out

I am a beginner learning c++, and currently making a singly linked list. I have faced some problems and I thought for a very long time, searched a lot but still do not have an answer for this code so I am begging for some help..
So this is my linked.h
template <class T>
class Node {
public:
T data;
Node<T>* next;
};
template <class T>
class List {
private:
Node<T> *head;
public:
List() : head(NULL) {};
~List() {
Node<T>* ptr, tmp;
for(ptr = head->next; ptr == NULL; ptr = head->next) {
delete ptr;
}
}
List(T* arr, int n_nodes) {
head = NULL;
Node<T> *tmp = head;
for(int i = 0; i < n_nodes; i++) {
Node<T>* node = new Node<T>;
node->data = arr[i];
if(head == NULL) {
head->next = node;
tmp = node;
}
else {
tmp->next = node;
node->next = NULL;
tmp = node;
}
}
}
friend std::ostream& operator<<(std::ostream& out, List<T>& rhs) {
Node<T>* cur = rhs.head;
out << cur;
while(cur != NULL) {
if(cur->next != NULL) {
out << cur->data << ", ";
cur = cur->next;
}
else
out << cur->data << " ";
}
return out;
}
};
and this is my main.cc file.
#include <iostream>
#include "linked.h"
int main() {
int array[5] = {12, 7, 9, 21, 13};
List<int> li(array, 5);
std::cout << li;
return 0;
}
I keep on getting segmentation fault when running the constructor and I don't get why. Where am I making a mistake? Any help would be appreciated!
You could cover the issue with a pointer to pointer:
List(T* arr, int n_nodes)
{
Node<T>** tmp = &head; // tmp *pointing* to uninitialized(!) head pointer
for(int i = 0; i < n_nodes; i++)
{
Node<T>* node = new Node<T>();
node->data = arr[i];
// now the trick:
*tmp = node; // !!!
// you now have assigned the new node to whatever pointer
// the tmp pointer points to - which initially is - guess - head...
// but we now need to advance!
tmp = &node->next;
}
// tmp now points to latestly created node's next pointer
// (or still head, if no nodes where created because of n_nodes == 0)
// be aware that this one still is not initialized! so:
*tmp = nullptr;
}
Your destructor necessarily fails, too:
Node<T>* ptr, tmp;
for(ptr = head->next; ptr == NULL; ptr = head->next)
{
delete ptr; // you delete ptr, but advancing (ptr = head->next)
// is done AFTERWARDS, so you'd access already deleted memory
// undefined behaviour
}
Additionally, you don't delete the head node! And if head is nullptr, you again have undefined behaviour.
Try it this way:
while(head)
{
Node<T>* tmp = head; // need a copy of pointer
head = head->next; // need to advance BEFORE deleting
delete tmp; // now can delete safely
}

Create and Display Linked List

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