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

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

Related

Deleting a node at nth position in a linked list in C++ ------ Last number is not getting deleted

On running this code, when I enter n as 4, the program stops instead of getting output as 2 4 6
I cant delete the last node in this linked list.
it works fine for all other position but not for the last node. Is it because the there is no (n+1)th node after the last node to which the (n-1)th node should point. and should I add some more code in the delete function explicitly to delete the last node?
#include<stdio.h>
#include<stdlib.h>
struct Node{
int data;
struct Node* next;
};
struct Node* head;
void Insert(int data, int n)
{
struct Node* temp1 = new Node();
temp1->data = data;
temp1->next = NULL;
if(n == 1)
{
temp1->next = head;
head = temp1;
return;
}
struct Node* temp2 = head;
for(int i = 0; i<n-2; i++)
{
temp2 = temp2->next;
}
temp1->next =temp2->next;
temp2->next = temp1;
}
void Print()
{
struct Node* temp = head;
while(temp != NULL)
{
printf("%d\n", temp->data);
temp = temp->next;
}
printf("\n");
}
void Delete(int n)
{
struct Node* temp1 = head;
if(n == 1)
{
head = temp1->next;
free(temp1);
return;
}
int i;
for(i = 0; i<n-2; i++)
{
temp1 = temp1->next;
struct Node* temp2 = temp1->next;
temp1->next = temp2->next;
free(temp2);
}
}
int main()
{
head = NULL;
Insert(2, 1);
Insert(4,2);
Insert(6,3);
Insert(5,4);
Print();
int n;
printf("Enter a position\n");
scanf("%d", &n);
printf("\n");
Delete(n);
Print();
}
Looks like you need to do a little more work on your delete algorithm. If you expand your test case to more than 4 nodes, I think you'll discover that there are more issues than just deleting the last node. I rewrote your delete function while trying to keep some of your same logic.
The comments mention some of your issues, but it looks like your for-loop calls free n-2 times. That's not what we want. We use the loop to "find" the node we want to delete, and then call free once (after reassigning the proper pointers)
void Delete(int n){
struct Node* temp1 = head;
if(n == 1)
{
head = temp1->next;
free(temp1);
return;
}
// Find the node right before the one you want to delete.
for(int i = 0; i<n-2; i++){
temp1 = temp1->next;
}
struct Node* node_to_be_deleted = temp1->next;
temp1->next = node_to_be_deleted->next;
free(node_to_be_deleted);
}
note: There's no error checking here...

Creating Linked List using For Loop (c++)

I was trying to create a linked list using a for loop but the 'new' in the for loop in the create() method didn't quite allocate a new slot to store new data. As a result, when I tried to print the list, I got an infinite loop. Can somebody tell me what's wrong here?
struct node
{
double value;
node * next_ptr;
node(){}
node(double val, node * p): value(val), next_ptr(p) {}
~node(){}
};
node * create()
{
using namespace std;
node temp = {0, nullptr};
node * result;
for(int i=1; i<5; ++i)
{
result = new node;
result->value = i;
result->next_ptr = &temp;
temp = *result;
}
return result;
};
The reason you are probably getting an infinite loop is because in:
temp = *result;
you are copying the value of *result into a new object of type node, which is unrelated to the one you created.
What you want to do is store a pointer instead:
node* temp = nullptr;
node* result;
for(int i=0; i<5; ++i)
{
result = new node;
result->value = i;
result->next_ptr = temp;
temp = result;
}
return result;
Live demo
A part from the learning value, just stick to std::forward_list or std::list, for lists, instead. Or even better just use std::vector or other containers (depending on the use that you make of the container).
a simple one to create linked in for loop
#include <iostream>
class LinkedList {
public:
int value;
LinkedList * next;
};
int main()
{
LinkedList *List = nullptr;
LinkedList *head = List;
LinkedList *prev;
for (int i=0; i< 3;i++)
{
LinkedList *temp = new(LinkedList);
temp->value = i;
temp->next = nullptr;
if (head == nullptr)
{
head = temp;
prev = head;
}
else
{
prev->next = temp;
prev = temp;
}
}
}

inserting element at the end of linked list

I am trying to insert element at the end of linked list but the while loop doesn't terminate. I am not able to understand why is this happening. Here is my code.
I am calling this function inside my main() function.
struct node{
int data;
struct node* link;
};
struct node * head;
void insert_last(int element){
struct node * temp = (node*)malloc(sizeof(struct node));
temp->data = element;
temp->link = NULL;
if(head==NULL){
head = temp;
}
struct node * temp1 = head;
while(temp1->link!=NULL){
temp1 = temp1->link;
}
temp1->link = temp;
}
Here is the main method:
int main()
{
head = NULL;
printf("Enter the no. of nodes or elements you want to make linked list of. ");
int n;
scanf("%d",&n);
int element = 0;
for(int i = 0; i<n; i++){
printf("Enter the element\n");
scanf("%d",&element);
insert_last(element);
std::cout<<"Element inserted\n\n";
}
//print_recursive(head);
print();
}
That's easy.
if(head==NULL){
head = temp;
}
In that case, you are already done with what are you doing. If you continue, temp1 becomes the temp. Then temp1->link = temp; makes this node point to itself. Second insertion will never find end because your list is circular now and while(temp1->link!=NULL) will never end.
What you should do is simply put return;.
if(head==NULL){
head = temp;
return;
}

Segmentation fault when creating linked list with function

I am trying to create a linked list and then echo the node values to the console. But using a function outside the main function and calling it is causing segmentation fault(core dumped). I can't figure it out why.
The following code works :
#include<iostream>
using std::cout;
using std::endl;
struct node
{
int val;
node* next;
};
void printList(node* start)
{
node* temp;
temp = start;
int i = 0;
while(temp->next != NULL)
{
cout<<"The value in the "<<i<<"th node is : "<<temp->val<<endl;
temp = temp->next;
i++;
}
}
int main()
{
node* start;
node* temp;
start = new node;
temp = start;
for(int i = 0; i < 10; i++)
{
temp->val = i*10;
temp->next = new node;
temp = temp->next;
}
temp->val = 0;
temp->next = NULL;
printList(start);
return 0;
}
But this throws a segmentation fault
#include<iostream>
using std::cout;
using std::endl;
struct node
{
int val;
node* next;
};
void createList(node* start)
{
node* temp;
start = new node;
temp = start;
for(int i = 0; i < 10; i++)
{
temp->val = i*10;
temp->next = new node;
temp = temp->next;
}
temp->val = 0;
temp->next = NULL;
}
void printList(node* start)
{
node* temp;
temp = start;
int i = 0;
while(temp->next != NULL)
{
cout<<"The value in the "<<i<<"th node is : "<<temp->val<<endl;
temp = temp->next;
i++;
}
}
int main()
{
node* start;
createList(start);
printList(start);
return 0;
}
Change void createList(node* start) to void createList(node*& start). (See it work).
In C++, unless specified otherwise, everything is passed by value. In this case, you're passing a pointer to a node (start) to createList by value. You can alter the node it points to (start->...), but not the pointer itself, as you're working with a copy.
Passing the pointer by reference allows you to change the pointer itself.
You're passing the start parameter into the function createList by value, which means that when you do
start = new node;
the copy of start is being assigned the address of the new node. This means that the start variable that you declare in main does not receive the address of the node.
To fix this, use a pointer reference. Pass start to createList by reference, instead of by value. Like this:
void createList(node*& start)
When you pass-by-reference, you're changing the pointer you declared in main directly, rather than creating a copy.

During free list, there is one segment error

Two functions, one is to create a link list, the other is to free the link list.
If the Create function return a double pointer to the head node, use this node to free the link list, will encounter a segment error. But if changing the Create function to return a pointer to head node, then free the list, this will be OK.
Anyone who can explain this for me? Here is the code which have the segment errors:
#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode{
int m_nValue;
ListNode* m_pNext;
}ListNode;
ListNode** CreateList(int data[], int length){
if(length<=0 || data == NULL)
return NULL;
ListNode *pHead = (ListNode*)malloc(sizeof(ListNode));
ListNode *pNode = pHead;
pNode->m_pNext = NULL;
pNode->m_nValue = data[0];
int i=1;
for(; i<length; i++){
ListNode *temp = (ListNode*)malloc(sizeof(ListNode));
temp->m_nValue = data[i];
temp->m_pNext = NULL;
pNode->m_pNext = temp;
pNode = temp;
}
return &pHead;
}
void FreeList(ListNode **pHead){
ListNode *pNode;
while(pHead!=NULL && *pHead!=NULL){
pNode = *pHead;
*pHead = pNode->m_pNext; // here will encounter an error;
free(pNode);
}
pHead = NULL;
}
int main(){
int data[] = {1,2,3,4,5};
ListNode **pHead = CreateList(data, sizeof(data)/sizeof(int));
FreeList(pHead);
}
But if I change the CreateList's return type to ListNode* CreateList(...), this will work well.
ListNode* CreateList(int data[], int length){
if(length<=0 || data == NULL)
return NULL;
ListNode *pHead = (ListNode*)malloc(sizeof(ListNode));
ListNode *pNode = pHead;
pNode->m_pNext = NULL;
pNode->m_nValue = data[0];
int i=1;
for(; i<length; i++){
ListNode *temp = (ListNode*)malloc(sizeof(ListNode));
temp->m_nValue = data[i];
temp->m_pNext = NULL;
pNode->m_pNext = temp;
pNode = temp;
}
return pHead;
}
int main(){
int data[] = {1,2,3,4,5};
ListNode *pHead = CreateList(data, sizeof(data)/sizeof(int));
FreeList(&pHead);
}
In ListNode** CreateList(int data[], int length) approach you are returning pointer to a local variable, which clearly goes invalid when the function returns.
That is, you declare a pointer variable ListNode* pHead in CreateList function and you return address of the variable pHead. The pointer variable pHead is stored in stack and when the CreateList function returns the stack is unwinded memory used to stored pHead is freed eventhough the memory pointed to by pHead is still availalbe on heap.