Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 months ago.
Improve this question
Please help me find the error in the given code, After returning the new head and using the printing function, no output gets displayed
Node *interChange(Node *head, int n){
Node *tempoo = head;
Node *temp = head;
int tot =0;
while(tempoo != NULL){
tempoo = tempoo->next;
tot++;
}
int count =0;
while(count < tot-n){
temp=temp->next;
count++;
}
Node *newHead = temp->next;
temp->next=NULL;
Node *newTemp = newHead;
while(newTemp != NULL){
newTemp = newTemp->next;
}
newTemp->next = head;
return newHead;
}
The last statement before the return performs an invalid dereferencing: newTemp->next = head; when at that point it is guaranteed that newTemp is NULL. This leads to undefined behaviour.
Your function returns the new head, so make sure the caller (which you didn't include) will use that new head pointer when printing the list.
Some other remarks:
The code does not deal well when the list is empty
The code does not deal well when n is greater than the number of nodes in the list, or is negative. It would maybe be a good idea to use modulo arithmetic to bring that value in range.
The cutoff point is wrongly calculated. For n is 0, the original head node will still become the new tail (if all the rest is corrected).
In C++ you should be using nullptr instead of NULL
Calling all your variables something like temp is not helpful. You can do with fewer variables, and use more telling names.
Here is a correction to your function:
Node *interChange(Node *head, int n) {
if (head == nullptr) return nullptr; // Boundary case
Node *tail = head;
int tot = 1; // We already have the head
// Check whether there is a next node, so we end up with the tail
while (tail->next != nullptr) {
tail = tail->next;
tot++;
}
// Make list circular
tail->next = head;
// Bring the n argument within a valid range
n %= tot;
// Find new tail
for (int count = tot - n; count; count--) {
tail = tail->next; // Reuse tail variable to identify new tail
}
// Reuse variable to identify new head
head = tail->next;
// Make list non-circular again
tail->next = nullptr;
return head;
}
The caller should capture the returned pointer. For instance:
Node *head;
// Initialise head with a list ...
// (your code here)
// And then:
head = interChange(head, 3);
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 months ago.
Improve this question
#include <stdlib.h>
#include <stdio.h>
struct Node{
int data;
Node* next;
};
Node* head;
void insert(int num){
Node* temp = new Node;
temp -> data = num;
temp -> next = NULL;
Node* temp1 = head;
while(temp1 -> next != NULL){
temp1 = temp1 -> next;
}
temp1 -> next = temp ;
}
void print(){
Node* temp2;
temp2 = head;
printf("Current list is:");
while(temp2->next != NULL){
printf(" %d", temp2 -> data);
temp2 = temp2 -> next;
printf("\n");
}
}
int main()
{
head = NULL;
insert(1);
insert(2);
insert(3);
insert(4);
insert(5);
insert(6);
insert(7);
insert(8);
print();
return 0;
}
This is supposedly programmed to insert an element at end of a linked list. however compiler showing segmentation fault without any useful traceback. tried finding; but couldn't get where is this getting wrong.
also used a debugger but it isn't helping as well.
In insert() the step Node* temp1 = head; you're assigning a nullptr to temp1, so therefore you cannot access its ->next element
In this case head = new Node(); in main() would fix your issue. Ignoring practices.
Node* temp1 = head;
while(temp1 -> next != NULL){
Consider what happens the very first time you call insert. The global head is still NULL, so temp1 is NULL, so accessing temp1->next is invalid.
You need to consider the case where head is NULL and assign the new node there.
That's of course aside from the general bad practice here (global variable, leaking memory all over the place, no encapsulation, no destructors, using NULL instead of nullptr, C headers, ...)
It looks like you never initialize head, meaning its value is always NULL. Then when you try to insert the first value into the linked list you try to access next on NULL.
Also, it looks like your print() function will never print the last element, because the last element's next is always NULL, therefore the condition in the while statement (temp2->next != NULL) is always false for the last element in the list.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I have a delete node based on position function and I am trying to do validation with the logic that the user input will repeat itself whenever the user's input is larger than the linked list size or in other words out of bound.
I declared int size and it'll increment itself whenever a new node is created, vice versa for remove node. Here is my remove node function:
void delete_position(int pos) //delete node with given position
{
node *current=new node;
node *previous=new node;
current=head;
if(head==NULL)
{
cout<<"You haven't ordered any cake(s)"<<endl;
}
for(int i=1;i<pos;i++)
{
previous=current;
current=current->next;
}
previous->next=current->next;
if(pos == 1){
node *temp=new node;
temp=head;
head=head->next;
delete temp;
}
size--;
}
Here is my validation, I used a do while loop to check the user's input, so whenever the input is larger than the size, it'll loop the user input once again. The problem is, say there are only 2 nodes in my list and I enter 4, the program jumps to the next line and ends.
cout<<"====destroy node===="<<endl;
cout<<"Which cake would you like to destroy?"<<endl;
do{
cin>>destroy_input;
}while(destroy_input > size);
list.delete_position(destroy_input);
Here is my code in pastebin: https://pastebin.com/vfuRYMLk
Re-polished my code : works for me, feel free to edit if anything is missing or wrong, i've gotten rid of the memory leak for this function, pretty new to this topic, sorry my previous mistakes.
void delete_position(int pos) //delete node with given position
{
node *current = head;
if(size == 1){
head=NULL;
tail=NULL;
}
else{
if(pos == 1){
head = head->next;
}else{
node *previous = NULL;
for(int i=1; i<pos; i++){
previous = current;
current = current->next;
}
if(current == tail){
previous->next =NULL;
tail = previous;
}else{
previous->next = current->next;
}
}
delete current;
size--;
}
}
There is a few bugs in your function.
void delete_position(int pos) //delete node with given position
{
node *current=new node; // New? Why?
node *previous=new node; // New? Why?
current=head; // current was not deleted. Memory leak.
Why do you create two nodes here? You are losing your pointer first thing in this function, so you definitely have a memory leak, and then you'll lose previous as soon as you enter the for. You're leaking two node.
for(int i=1;i<pos;i++) // start at position 1, since you already have head.
{
previous = current;
current = current->next;
}
previous->next = current->next;
Note that if the position of the node to delete is 1, you never enter the for loop. But still, you're assigning previous->next to current->next. In your case, previous is set to a new node that has been initialized to default value. In short, a new node that is not in your list gets the value of head->next.
if(pos == 1)
{
node *temp = new node; // create a new node again? Why?
temp = head; // You lost your newly created memory. New memory leak here.
head = head->next;
delete temp;
}
size--;
If the condition passes, then you create a new default node. You swiftly lose the pointer to overwrite it with the pointer value of head. It then becomes the second node and is deleted.
Is your list 1-based? It seems that you tried to make a special case for head when pos == 1.
If it's supposed to be 0-based, a better solution would be :
bool delete_position(int pos) //delete node with given position
{
node *current = head;
node *previous = nullptr;
bool deleted = false;
// If your list is 1-based, though I don't see why it would be, uncomment the following line.
// pos--;
if((size > 0) && (pos < size))
{
// Search fo the node
for(int i = 1; i < pos; i++)
{
previous = current;
current = current->next;
}
// Connect next node with previous node (if it's not head)
if(previous)
{
previous->next = current->next;
}
// Remove the current node
delete current;
size--;
deleted = true;
}
return deleted;
}
I haven't analyzed all your program, but I suspect that you may have a few other memory leaks floating around. Look for new that doesn't have a corresponding delete.
I am writing a function that inserts a new element in a singly linked linked list.
The function accepts the *head to the list, the data to be put in the new element and the position in the l-list should be inserted at.
This is the link to the programming exercise in case I've not been clear enough.
The following code works perfectly -
/*
Insert Node at a given position in a linked list
head can be NULL
First element in the linked list is at position 0
Node is defined as
struct Node
{
int data;
struct Node *next;
}
*/
Node* InsertNth(Node *head, int data, int position)
{
//Takes head of list as input and returns it after inserting a new element
//with `data` at `position` in the l-list
Node *temp = new Node;
temp = head;
Node *newn = new Node;
newn->data = data;
if(position == 0){
newn->next = head;
return newn;
}
while(--position){
temp = temp->next;
}
newn->next = temp->next;
temp->next = newn;
return head;
}
However, I don't understand why I had to use Node *temp = new Node; temp = head;.
Why doesn't simply using Node *temp = head; work?
I'm only using the temp pointer to traverse the l-list so that I can preserve the location of the head when I return the final list.
Edit - I understand that Node *temp = head; is the way to go. This was how I originally programmed it too, but I forgot to mention that this is what's giving me a segfault. When I change it to Node *temp = new Node; temp = head; it works for all the testcases(including the ones where head is NULL).
Why must this seemingly absurd mem allocation seem to make it work is what I want to know.
The code you post above leaks.
Node *temp = new Node; temp = head;
This is no good.
Node *temp = head;
This is better.
There are other problems in your code; but your analysis that it was silly to new then immediately reassign the pointer is correct. Well spotted.
The answers that were posted before mine are both wrong, sure they Point out that your code leaks, but they didn´t check the rest of the code to see if it actually does what it is supposed to do. Your code is prone to Errors, because you don´t account for the head being NULL, which is clearly stated.
// Returns the new node inserted at the given Position inside the l-list
Node* InsertNth(Node *head, int data, int position)
{
Node *newn = new Node;
newn->data = data;
newn->next = 0;
// No head, return node right away
if(!head)
{
return newn;
}
// Exception - only case where head is not returned
else if(!position)
{
newn->next = head;
return newn;
}
// Create ´temp´ which is a pointer to the next node in the list
Node *temp = head;
// The function allows passing of a signed int, make sure we stay above 0
// as the previously while(--position) would go into an endless loop
// if a signed integer were passed on to the function
while(--position > 0)
{
// Just incase the input is bad, and position exceeds the size of the list
if(!temp->next)
{
break;
}
temp = temp->next;
}
// Now that we found the place in line, insert it between the temp and the next item
// in the list. Which may also be NULL
newn->next = temp->next;
temp->next = newn;
return head;
}
Now as you can see a few changes were made, the code earlier on didn´t account for head being NULL, and it didn´t properly set the member ´next´ to 0, which would lead to a Crash eventually if someone iterated over the supposedly null-terminated single-linked list.
Use of
Node *temp = new Node;
temp = head;
causes a memory leak. Memory allocated in the first line is lost. You need to use:
Node *temp = head;
I've been working on this for about a day and haven't been able to put a series of nodes in the middle of a linked list. In all, the program I'm trying to write takes a string, another string and an integer, and places the second string at the integer location in the linked list made from the first string. I've tried quite a few strategies but they've all met with unresponsive programs and segmentation faults. My code is below:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
typedef struct node
{
int number;
char j;
struct node* next;
struct node* prev;
}node_t;
void print(node_t *head)
{
node_t *curr = head;
while(curr)
{
printf("\n%d%c\n", curr->number, curr->j);
curr = curr->next;
}
}
void insert(int index, node_t *head, node_t *tail, char* string)
{
node_t *curr = head;
node_t *newNode = (node_t*)malloc(sizeof(node_t));;
node_t *newPrev = (node_t*)malloc(sizeof(node_t));;
node_t *newNext = (node_t*)malloc(sizeof(node_t));;
int i;
while(curr->number!=index)
{
curr = curr->next;
}
//printf("\n%d%c\n", curr->number, curr->j);
newNode->prev = curr;
newNode->next = curr->next;
newNext = curr->next;
curr->next = newNode;
curr = curr->next;
for(i=0; i<strlen(string); i++)
{
curr=(node_t*)malloc(sizeof(node_t));
curr->number = i;
curr->j = string[i];
curr->prev = tail;
tail->next = curr;
tail = curr;
}
newNext->prev = curr;
}
int main()
{
node_t *curr,*head,*tail;
head=NULL;
tail=NULL;
int i;
int index = 0;
char* inputString = (char*)malloc(sizeof(char)+1);
char* inputString2 = (char*)malloc(sizeof(char)+1);
printf("Please input a string: ");
gets(inputString);
printf("%s\n", inputString);
for(i=0; i<strlen(inputString); i++)
{
curr=(node_t*)malloc(sizeof(node_t));
curr->number = i;
curr->j = inputString[i];
curr->next = NULL;
if(tail)
{
curr->prev = tail;
tail->next = curr;
}
tail=curr;
if(!head)
{
head=curr;
}
}
printf("Please input a string: ");
gets(inputString2);
printf("%s\n", inputString2);
printf("Please input a valid index: ");
scanf("%d", &index);
while(index>strlen(inputString)||index<0)
{
printf("A valid index. ");
scanf("%d", &index);
}
printf("%d\n", index);
insert(index, head, tail, inputString2);
print(head);
return 0;
}
I'd be eternally grateful if anyone could provide a way to insert the second string into the linked list as elements. I've determined that it works as far as identifying the node specified by the integer, but beyond that I'm not sure. Thanks in advance.
EDIT: Now my issue is that the program puts an rubbish node at the correct place, but then creates the nodes at the end of the list.
There are still so many problems with your code that it is probably impossible to help you in this forum without simply giving you "the answer". You might try a different website.
Some hints:
Since it is possible for head and/or tail to be modified in the insert function, you need to pass in their addresses, not just their values. I.e.,
void func(node_t **head) {
// dereference head (with *) to use it
*head = malloc(sizeof(node_t));
}
void another_func() {
node_t *head = NULL;
func(&head); // pass the address of head
}
newPrev is unused (are you compiling with a proper warning level? With gcc, add the -Wall flag).
newNext doesn't need any malloced space since it is used to point to previously-allocated space.
And there are other errors (logic errors) more difficult to describe.
My advice it to rewrite it. Declare another struct called list to hold the head and tail pointers. Write a function called make_node to create and initialize a new node given a character (and a number if you think that's necessary). Write a function called make_list that takes a string and returns a list of its characters. In the insert function, use make_list to make a list from the string to be inserted and then modify the pointers to insert it into the first list.
Storing the index numbers in the nodes is unnecessary and actually complicates things since to keep them in order you'd need to update the indices in the original list after the insertion. You can simply keep a count of how many nodes you've looped through to know the index of a node.
Adding the C language tag to your question may bring others in to help you.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 8 years ago.
Improve this question
The code hangs while executing. Please help me to understand what is the problem here
It stcks after the first travers and does not even enters the reverse function. Could not understand the issue:
Help me on it.
# include<iostream>
# include<stdlib.h>
using namespace std;
struct sLL
{
int data;
sLL * next;
};
void createList(sLL ** head, int n)
{
if(n == 0)
{
return;
}
sLL * temp = (sLL *) malloc(sizeof(sLL));
if(temp != NULL)
{
temp->data = rand() % 100;
temp->next = NULL;
*head = temp;
//head = &(temp->next);
createList(&(temp->next), n - 1);
}
}
void traverse(sLL * head)
{
cout<<"In traverse"<<endl;
while(head) {
cout<<head->data<<"->";
head=head->next;
}
cout<<"NULL"<<endl;
cout.flush();
return;
}
sLL* reverse(sLL * head)
{
sLL * temp = NULL, * newNode = NULL;
while(head) {
newNode = head->next; // to traverse forword
head->next = temp;
temp = head; // Current node value which we use in next itr as a previous node value.
newNode = head; // assigning newNode vlaue back to head so that we can traverse forward.
}
return temp; // final node value will be in temp i.e the current node value.
}
int main()
{
int n;
sLL * head = NULL, *temp = NULL;
cout<<"Enter the number of nodes :";
cin>>n;
createList(&head, n);
cout<<"\nCreate Done"<<endl;
traverse(head);
cout.flush();
cout<<"Reverse Start";
temp = reverse(head);
cout<<"reverse done";
traverse(temp);
}
You don't reassign the head value at all
while(head)
//loop
Here, the head pointer is never altered. So the loop is an infinite one.
Your comment contradicts the code here:
newNode = head; // assigning newNode vlaue back to head so that we can traverse forward.
If you do what the comment says it should work better:
head = newNode; // assigning newNode value back to head so that we can traverse forward.