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 years ago.
Improve this question
I have written a code in the C language which will create a linked list. The linked list structre has two fields, namely data and next; data contains integer data, next is a structure pointer.
The program asks the user to input data into the list. Once the data has been entered, the program will go through the list and check which data in the node contains a prime number. If it finds one such node, it will delete it and link the next node to the previous node, but I am getting a segmentation fault error and I am unable to solve.
I am putting below the code. Can you please be kind enough to help me solve it as I do not know how to find the problem?
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
typedef struct node *nptr;
nptr H, h, n;
void deletetheprime(struct node**);
void display();
int prime(int);
int main() {
nptr temp1, temp;
int i, N, p;
printf("\n if list is completed enter 999\n");
for (;;) {
printf("\n enter the data \n");
scanf("%d", &i);
if (i == 999)
break;
else
if (H == NULL) {
H = h = (nptr)malloc(sizeof(struct node));
H->data = i;
H->next = NULL;
} else {
n = (nptr)malloc(sizeof(struct node));
n->data = i;
n->next = NULL;
h->next = n;
h = n;
}
}
printf("\n data before deletion\n");
display();
temp = H;
while (temp != NULL) {
N = temp->next->data;
p = prime(N);
if (p == 1) {
deletetheprime(&temp);
} else {
temp = temp->next;
}
}
printf("\n the data after deletion is\n");
display();
return 0;
}
void deletetheprime(struct node **temp2) {
nptr temp, temp1;
temp = *temp2;
temp1 = temp->next;
temp->next = temp->next->next;
free(temp1);
temp = temp->next;
}
int prime(int i) {
int j, p = 0;
for (j = 2; j <= i / 2; i++) {
if (i % j == 0) {
break;
}
}
if (j > i / 2) {
p = 1;
}
return p;
}
void display() {
nptr temp;
temp = H;
while (temp != NULL) {
printf("\n %d", temp->data);
temp = temp->next;
}
}
The problem is here:
while (temp != NULL) {
N = temp->next->data;
When you reach the last element of the list, temp is not NULL, but temp->next is so temp->next->data has undefined behavior.
There are other problems:
your prime() function is inefficient and will return 1 for 0 and 1.
you deletetheprime() function deletes the node and updates the pointer in the callers scope, but the caller does not update the link in the previous node nor the H pointer if the deleted node is the first.
you use global variables for no good reason, you should pass H to display() and make all variables local in main().
you never free the allocated objects, it is good style to free everything you allocate.
you should not hide pointers behind typedefs, make node a typedef for struct node but keep pointers visible, it is a good habit to avoid confusing both the reader and the programmer.
To delete the node, you should use the pointer to link trick:
for (struct node **p = &H; *p;) {
if (prime((*p)->data) {
nptr np = *p;
*p = np->next;
free(np);
} else {
p = &(*p)->next;
}
}
p initially points to the head pointer H and subsequently points to the next member of the previous node. It can be used to update the head pointer or the link in the previous node when a node to be deleted is found.
Here is a corrected and simplified version:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
int isprime(int n) {
if (n < 2)
return 0;
if (n % 2 == 0)
return n == 2;
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
void display(const node *temp) {
while (temp != NULL) {
printf(" %d", temp->data);
temp = temp->next;
}
printf("\n");
}
int main(void) {
node *H = NULL;
node **lastp = &H;
node *n;
int i;
printf("Enter values, when list is completed enter 999\n");
for (;;) {
printf("\n enter the data: ");
if (scanf("%d", &i) != 1 || i == 999)
break;
n = malloc(sizeof(*n));
if (n == NULL)
break;
n->data = i;
n->next = NULL;
*lastp = n;
lastp = &n->next;
}
printf("\n data before deletion: ");
display(H);
for (node **p = &H; *p;) {
if (isprime((*p)->data)) {
n = *p;
*p = n->next;
free(n);
} else {
p = &(*p)->next;
}
}
printf("\n the data after deletion is: ");
display(H);
/* free the list */
while (H != NULL) {
n = H;
H = n->next;
free(n);
}
return 0;
}
I shall attribute your please solve it! stance to your poor command of the English language. Please learn to improve both your communications and your programming skills by carefully studying answers on this site.
The problem occurs here, in main
while(temp!=NULL)
{
N=temp->next->data;
...
You are checking if temp is not NULL, which is correct, but accessing data of next node, which can be NULL, and has to be NULL near the end of the list, which leads to undefined behavior.
Simply modify it to
while(temp!=NULL)
{
N=temp->data;
...
Where you are sure that temp isn't NULL and you won't get segmentation error here. And it'll work.
Or if you need to access data of temp->next->next node, you've got to check if next->next isn't NULL as well.
while(temp!=NULL)
{
if (temp->next->next != NULL)
{
N=temp->next->data;
}
else // temp->next->next is NULL so you can't access the data
...
Related
I am building a program for a project. One of the requirements for the project is a function that selects a random node from my linked list of 3000 words.
I tried to do this by creating a function that generates a random number from 0 to 2999. After this, I created another function that follows a for loop starting from the head and moving to the next node (random number) times.
My random number generator is working fine, but my chooseRand() function is not.
Please help, the random number generator and the chooseRand() function are the last two functions above main. Also, my code is a bit messy, sorry.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int nodeNum;
int chances;
char* secret;
/*Node of linked list*/
typedef struct node {
char *data;
struct node *next;
} node;
node *start = NULL;
node *current;
/*Void function to print list*/
void printList(struct node *node)
{
while (node != NULL) {
printf("%s ", node->data);
node = node->next;
}
}
/*Appending nodes to linked list*/
void add(char *line) {
node *temp = malloc(sizeof(node));
temp->data = strdup(line);
temp->next = NULL;
current = start;
if(start == NULL) {
start = temp;
} else {
while(current->next != NULL) {
current = current->next;
}
current->next = temp;
}
}
void readfile(char *filename) {
FILE *file = fopen(filename, "r");
if(file == NULL) {
exit(1);
}
char buffer[512];
while(fgets(buffer, sizeof(buffer), file) != NULL) {
add(buffer);
}
fclose(file);
}
node *listSearch(node* start, char *nodeSearched){
node *p;
for (p = start; p != NULL; p = p->next)
if (strcmp(p->data, nodeSearched) == 0)
printf("%s", p->data);
return NULL;
}
node *letterSearch(node* start, int i){
node *p;
for (p = start; p != NULL; p = p->next)
if (strlen(p->data) == i)
{
printf("\n %s", p->data);
free(p);
p = NULL;
}
return NULL;
}
void chooseRand(struct node* start)
{
node* p;
int n;
p = start;
for(n = 0; n != nodeNum; n++)
{
p = p->next;
}
printf("%s", p->data);
}
void randNum(int lower, int upper)
{
srand(time(0));
nodeNum = (rand() % (upper - lower + 1)) + lower;
}
int main(){
randNum(0, 2999);
chooseRand(start);
return 0;
}
As others has said, the problem is that you don't have initialized the linked list yet, because of what your are getting a segmentation fault. So, in addition to initializing the list first, you must also introduce checks in the implementation of the chooseRand function, to check that if you reach the end of the list, without reaching the desired index, you stop executing the foor loop, otherwise you will be potentially exposed to segmentation faults.
Improve chooseRand implementation, to prevent segmentation fault either, when the linked list is empty, or when the randomly generated nodeNum is grater than the the index of the list's last item:
void chooseRand(struct node* start)
{
node* p;
int n;
p = start;
if(p == NULL){
printf("The list is empty!");
return;
}
// Also, we must stop the iteration, if we are going to pass the end of the list, you don't want a segmentation fault because trying to access a NULL pointer:
for(n = 0; n != nodeNum && p->next != NULL; n++)
{
p = p->next;
}
// If p == NULL, the list was not big enough to grab an item in the `nodeNum` index:
printf("%s", (n != nodeNum) ? "Not found!" : p->data);
}
Initialize the linked list, with the content of some file on disk:
int main(){
randNum(0, 2999);
// Fill the linked list with the content of a file in disk, calling your method:
char fileName[] = "PutYourFileNameHere.txt";
readfile(fileName);
chooseRand(start);
return 0;
}
There is another fix that you must do, and it is free the memory being hold by the pointer field data of your structure, in the implementation of your method letterSearch. Inside the if statement, you're de-allocating the memory hold by the p pointer, but you aren't de-allocating the memory assigned to the pointer p->data, this will cause a memory leak. When you in the function add, initialized p->data with the result of the call to the function strdup(line), what this function does is allocate enough memory in the heap, copies to it the buffer pointed by the line argument, and give to you back a pointer to the new allocated memory, that you're storing in the p.data field; a pointer that you should free when you're done with it, otherwise your program will have potential memory leaks. So I will modify your function letterSearch as folollows:
node *letterSearch(node* start, int i){
node *p;
for (p = start; p != NULL; p = p->next)
if (strlen(p->data) == i)
{
printf("\n %s", p->data);
// Free p->data before free p:
free(p->data);
free(p);
p = NULL;
}
return NULL;
}
References:
strdup
The result of code 1 is still 10 after you free pointer p and p is not NULL.
the inputs of code 2 are 5 (length) and 1 2 3 4 5 for the value of each node, but the output is nothing under the condition that all the following nodes are not NULL.
My question is that based on the logic of code 1, shouldn't all the values of nodes be printed because they are not NULL?
Can anyone explain to me? Thank you so much!
code 1:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *p = (int*)malloc(sizeof(int));
*p = 10;
free(p);
if (p != NULL) {
printf("%d\n", *p);
}
return 0;
}
code 2:
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
struct Node *next;
int value;
} Node, *list;
list create_Node() {
list head = (list)malloc(sizeof(Node));
if (!head)
exit(-1);
list tail = head;
int len;
int val;
printf("Please enter the length of the list:\n ");
scanf("%d", &len);
for (int i = 0; i < len; i++) {
list new = (list)malloc(sizeof(Node));
if (!new)
exit(-1);
printf("Please enter the value of the node:\n ");
scanf(" %d", &val);
new->value = val;
tail->next = new;
tail = new;
}
return head;
}
int delete_List(list l) {
if (l == NULL) {
printf("List is empty!");
exit(-1);
}
list temp;
while (l) {
temp = l->next;
free(l);
l = temp;
}
return 1;
}
int main() {
Node *n = create_Node();
n = n->next;
delete_List(n);
while (n->next != NULL) {
printf("%d\n", n->value);
n = n->next;
}
return 0;
}
...based on the logic of code 1...
Code 1 accesses freed memory (a so-called dangling pointer), which is undefined behavior. Anything can happen, including, but not limited to, your program crashing, the last value being returned (= the behavior you observed) or the program doing something completely unexpected.
Thus, you cannot infer anything from "the logic of code 1".
having
int main(){
int *p = (int*)malloc(sizeof(int));
*p = 10;
free(p);
if(p!=NULL)
{
printf("%d\n",*p);
}
return 0;
}
My question is that based on the logic of code 1, shouldn't all the values of nodes be printed because they are not NULL??
Except in the case there are no more memory the malloc will works and return a non null value, after the free the value of p is unchanged and still non null so the code try to read in the free memory and this is an undefined behavior
There are better way to ( try to) print a random value :-)
in code 2 this is the same, you access to free memory, both in the test of the while and in the printf and the value to assign n
I am trying to create a linked list and sort it by Bubble Sort. I succeeded to create the linked list, but when I am trying to Bubble Sort it, some accidents occur and I do not know the problem. What is the problem?
#include <stdio.h>
#include <stdlib.h>
//the struct of LinkedList
typedef struct Node
{
int data;
struct Node * pNext;
}NODE,*PNODE;
PNODE createList();//Creat one LinkedList
int lengthList(PNODE pHead);//get the length of LinkedList
void sortList(PNODE);//bubble sort
int main()
{
int length;
PNODE pHead=NULL;
pHead=createList();
sortList(pHead);
return 0;
}
//Create LinkedList
PNODE createList()
{
int i,n;
int val;
PNODE pHead=(PNODE)malloc(sizeof(NODE));
if(pHead==NULL)
{
printf("failed to create!\n");
exit(-1);
}
pHead->pNext=NULL;
PNODE pTail=pHead;
printf("please input the length of the LinkedList:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("number %d is:\n",i+1);
scanf("%d",&val);
PNODE pNew=(PNODE)malloc(sizeof(NODE));
if(pNew==NULL)
{
printf("failed to create\n");
exit(-1);
}
pNew->data=val;
pTail->pNext=pNew;
pNew->pNext=NULL;
pTail=pNew;
}
return pHead;
}
//get the length of LinkedList
int lengthList(PNODE pHead)
{
int i=0;
PNODE p=pHead->pNext;
while(p!=NULL)
{
i++;
p=p->pNext;
}
return i;
}
//bubble sort
void sortList(PNODE pHead)
{
int i,j,t,len;
PNODE p,q;
len=lengthList(pHead);
p=pHead->pNext;
for(i=0;i<len-1;i++)
{
for(j=0;j<len-i;j++)
{
q=p->pNext;
if( p->data > q->data)
{
t=p->data;
p->data=q->data;
q->data=t;
}
p=q;//here may be the error
}
}
return;
}
You are running off the end of your list in sortList
p=pHead->pNext;
for(i=0;i<len-1;i++)
{
for(j=0;j<len-i;j++)
{
q=p->pNext;
....
p=q;//here may be the error
}
}
Bug 1) Your list is only len long but you are attempting to advance p to p->pNext far more then len times.
Bug 2) pHead does not need to be a full NODE - it's just a PNODE pointer. You never use its data field. You should have pHead point to the first node in the list, and then start your iteration at pHead rather than pHead->pNext.
Bug 3) You never clean up your memory allocations.
As #Airsource pointed out the bugs, keep in mind most of them are caused because of poor designing choice of your program. Try to do it like below & you will run into less errors
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct _Node{
int data;
struct _Node* next;
}Node;
typedef struct {
Node* headPtr;
Node* tailPtr;
unsigned size;
}List;
static void create_node(List* list, int element) {
if (list->headPtr == NULL) {
// List is empty
list->headPtr = (Node* )malloc(sizeof(Node));
list->headPtr->data = element;
list->headPtr->next = 0;
list->tailPtr = list->headPtr;
list->size++;
}else{
// List was already populated
Node* temp = (Node* )malloc(sizeof(Node));
temp->data = element;
temp->next = 0;
list->tailPtr->next = temp;
list->tailPtr = temp;
list->size++;
}
}
void create_list(List* list, int length){
int ele;
int i;
list->headPtr = list->tailPtr = 0;
list->size = 0;
for (i = 0; i < length; i++) {
scanf("%d", &ele);
create_node(list, ele);
}
}
void print_list(List* list){
Node* loop = list->headPtr;
while(loop){
printf("%d ", loop->data);
loop = loop->next;
}
printf("\n");
}
int main(){
List* list;
int n;
printf("Enter the length of the list: ");
scanf("%d", &n);
create_list(list, n);
print_list(list);
bubble_sort(list);
print_list(list);
if (cleanup(list))
printf("Memory rescued!!\n");
else
printf("OOPS!! Error\n");
return 0;
}
Moreover, you can get the size anytime just by list->size. No need for separate function to do that.
Finally to sort it using bubble sort you could do something like this below
void bubble_sort(List* list) {
int i, j;
Node* first, *second;
int temp;
first = list->headPtr;
second = list->headPtr->next;
for (i = 0; i < list->size - 1; i++) {
for (j = 0; j < list->size - i - 1; j++) {
if (first->data > second->data){
temp = first->data;
first->data = second->data;
second->data = temp;
}
first = second;
second = second->next;
}
first = list->headPtr;
second = list->headPtr->next;
}
}
and for cleanup you do this
bool cleanup(List* list) {
Node* curr = list->headPtr;
Node* nxt = list->headPtr->next;
while(nxt){
free(curr);
curr = nxt;
nxt = curr->next;
}
list->headPtr = list->tailPtr = 0;
list->size = 0;
return !nxt ? true: false;
}
There are couple of bugs in your program. I will address them one by one:
Line 28 PNODE pHead=(PNODE)malloc(sizeof(NODE));
Here you are allocating a memory and creating a node before checking if n>0 or not.
Line 36 printf("please input the length of the LinkedList:");
Now up to this point you have created a one node, head node which has no value in it (so contains garbage)
In effect your createList() creates a linked list with n+1 nodes instead of n and the head->value contains garbage.
Solution:
printf("please input the length of the LinkedList:");
scanf("%d", &n);
for(i=0; i<n; i++)
{
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(pNew == NULL)
{
printf("failed to create!\n");
exit(-1);
}
scanf("%d", &val);
pNew->data = val;
pNew->pNext = NULL;
if (!i)
pHead = pNew;
else
pTail->pNext = pNew;
pTail = pNew;
}
return pHead;
Line 59 PNODE p=pHead->pNext;
Here you are counting nodes starting from the second node (leaving out head). No wonder you will get length as n as you have created a linked list of length n+1 in your createList()
Imagine what if n = 0 and thus pHead = NULL?
Then this line will result in SegFault.
Solution:
change PNODE p=pHead->pNext; to PNODE p = pHead;
Line 73 p=pHead->pNext;
Here you will start sorting excluding the first node, head node.
Also this should be inside the outter for and outside of the inner for to reset the p to first node for each pass.
Line 76 for(j=0;j<len-i;j++)
Here j must be less than len - 1 - i as in pass 1 (i = 0) in the worst case j will be equal to len-1 for j < len-i, where p will point to the last node of linked list and q will be NULL as q = p -> pNext. Which will make q->data to result in SegFault.
To summarise, your sort routine is producing SegFault in the very first Pass and even if it didn't (by properly adjusting the loop-terminating expression in inner for) the outer for loop is contributing nothing towards the sorting except increasing the time complexity.
Solution:
for(i = 0; i < len - 1; i++)
{
p = pHead;
for(j = 0; j < len - 1 - i; j++)
{
q = p -> pNext;
if(p->data > q->data)
{
t = p -> data;
p -> data = q -> data;
q -> data = t;
}
p = q;
}
}
A question:
How are you checking whether element have been sorted or not?
A printList() routine would have been helpful in spotting the above bugs.
"Always verify whether you correctly stored the input or not by explicitly printing the same before processing it!"
I have a Segmentation error, maybe a lot more after I run it, but I can't check anything else now because of that.
The program should work like this:
When user types in 5 numbers, they should print out in ascending order
If the user enter the number already exit, then remove the original value
If the user enter a native value, print List Backwards
This is my code so far:
#include <stdio.h>
#include <stdlib.h>
struct element {
int i;
struct element *next;
};
void insert (struct element **head, struct element *new)
{
struct element *temp;
temp = *head;
while(temp->next != NULL)
{
if((*head==NULL))
{
head = malloc(sizeof(struct element));
//temp->i = i;
temp->next = new;
new = temp;
}
else if(temp->i == new->i)
{
new = malloc(sizeof(struct element));
free(new);
//purge(&head,&new);
}
else if(temp->i < new->i)
{
temp->i = new->i;
}
else if(temp->i > new->i)
{
new = new->next;
}
}
}
void purge (struct element *current, struct element *predecessor)
{
predecessor->next = current -> next;
free(current);
}
void printList (struct element *head)
{
while(head)
{
printf("%d", head -> i);
head = head->next;
}
}
void printListBackwards (struct element *ptr)
{
if(ptr == NULL)
{
printf("list is empty \n");
return;
}
if(ptr->next != NULL)
{
printListBackwards(ptr->next);
}
printf("print %p %p %d\n", ptr, ptr->next, ptr->i);
}
int main()
{
int n = 0;
int count = 5;
printf("enter a Number: \n");
scanf("%d",&n);
struct element *new;
new = malloc(sizeof(struct element));
struct element *head = NULL;
new->i = n;
while(count!=0)
{
insert(&head,new);
printList(head);
count++;
}
}
In the main() function, you only allocate and create one element with malloc(); you then try to add it to your list 5 times. This is going to cause confusion. You should allocate a node once for each element you add to the list.
struct element *head = NULL;
while (count!=0)
{
printf("enter a Number: \n");
if (scanf("%d", &n) != 1)
break;
struct element *new = malloc(sizeof(struct element));
if (new == 0)
break;
new->i = n;
new->next = NULL;
insert(&head, new);
printList(head);
count--;
}
Note that the revised code checks the result of both scanf() and malloc(). It also sets the new element's next pointer to NULL. And it counts down rather than up; this is likely to use less memory.
I've not tested this so there could be (and very probably are) other problems, but this is likely to work better (fix some of the problems, but not all of the problems).
You do need to learn how to use a debugger, at least enough to get the stack trace so you know which line of code is causing the crash.
Do you really need a linked list? It seems the problem statement says that user can enter only 5 numbers... if so, why not just use an array of 5 elements? Following are some ideas.
enum { N = 5 };
typedef struct Element {
int number;
bool present;
} Element;
Element elements[ N ];
Init:
for( i = 0; i != N; ++i ) {
elements[i].number = 0;
elements[i].present = false;
}
Insert "inputNumber":
for( i = 0; i != N; ++i ) {
if( elements[i].present == false ) {
elements[i].number = inputNumber;
elements[i].present = true;
}
}
Remove "removeNumber":
for( i = 0; i != N; ++i ) {
if( elements[i].number == removeNumber ) {
elements[i].present = false;
}
}
Print Backwards:
for( i = N; i != 0; --i ) {
printf( "%d\n", elements[i].number );
}
In main, you should set new->next = NULL; [or somewhere in the beginning of insert]
This bit of code is just messed up:
head = malloc(sizeof(struct element));
//temp->i = i;
temp->next = new;
new = temp;
You should, probably, set
*head = new;
But you also need to set *head->next = NULL;
This bit is complete nonsense:
new = malloc(sizeof(struct element));
free(new);
//purge(&head,&new);
You would want to free new.
else if(temp->i < new->i)
{
temp->i = new->i;
}
else if(temp->i > new->i)
{
new = new->next;
}
This is also quite wrong. I think the last one should do
temp = temp->next;
Do yourself a favour, draw up on a piece of paper, boxes
HEAD
!
v
+-----+
! i=3 !
+-----+ +-----+
!------->! i=4 !
+-----+
!-------->NULL
And then walk through it and see how your code inserts, removes, etc.
[Can I also suggest that you don't use C++ reserved words in your code - new is a C++ reserved word. It means that your code CERTAINLY won't compile in a C++ compiler, which is a bad thing to prevent. Sure, there are several other things that may need changing, but a simple thing like "not calling a variable new" shouldn't be one of the things it fails on].
I am supposed to do a program which can do polynomial addition/subtraction/multiplication/evaluation using circular linked list.
My multiplication code is going in infinite loop, and I have marked a comment where it is happening (detected with printf statements, removed).
list* poly_mul(list *p1, list *p2) {
term tmp;
list *result = malloc(sizeof(list));
memcpy(result, p1, sizeof(list));
node *b = p2->head;
node *r = result->head;
do {
do {
tmp.exp = r->data.exp + b->data.exp;
tmp.coeff = r->data.coeff * b->data.coeff;
unsigned int add_term = 1;
node *c = result->head;
do {
if(c->data.exp == tmp.exp) {
c->data.coeff += tmp.coeff;
add_term = 0;
break;
}
c = c->next;
//Here it goes in infinite loop
} while(c != result->head);
if(add_term)
node_add(result, &tmp);
b = b->next;
} while(b != p2->head);
r = r->next;
} while(r != result->head);
return result;
}
The structures used are here:
typedef struct {
int exp;
int coeff;
} term;
typedef struct node {
term data;
struct node *next;
} node;
typedef struct {
node *head;
node *tail;
unsigned int count;
} list;
And this is the code in main:
void main() {
list p1, p2, *p3;
p1.count = p2.count = 0;
poly_create(&p1);
p3 = poly_mul(&p1, &p2);
poly_print(p3);
}
void poly_create(list *l) {
int i, n;
printf("\nEnter number of terms in the polynomial: ");
scanf("%d", &n);
for(i = 1; i <= n; i++) {
printf("\nEnter details for term %d: ", i);
term_append(l);
}
void node_add(list *l, term *t) {
node *tmp = malloc(sizeof(node));
memcpy(&tmp->data, t, sizeof(term));
if(l->count == 0) {
l->head = tmp;
l->tail = tmp;
tmp->next = tmp;
}
else {
l->tail->next = tmp;
tmp->next = l->head;
l->tail = tmp;
}
l->count++;
}
void term_append(list *l) {
term t;
enter:
printf("\nEnter term as <coefficient>,<exponent>: ");
scanf("%d,%d", &t.coeff, &t.exp);
if(!t.coeff) {
printf("\nCoefficient is zero, reenter term");
goto enter;
}
if(l->count >= 1) {
node *i = l->head;
do {
if(i->data.exp == t.exp) {
printf("\nExponent %d was already entered, reenter term", t.exp);
goto enter;
}
i = i->next;
} while(i != l->head);
node_add(l, &t);
}
else
node_add(l, &t);
}
Please get me a solution for this problem, I've been trying to solve this for the past three hours.
Why is it going into an infinite loop? You can find out by using a debugger and stepping through the code. Just put a breakpoint at the appropriate place and you should be able to find it yourself. In all likelihood, you have a loop in your linked list.
You can check for loops in your linked list with two pointers. The first one (tail) point to the start of your list. The second (head) points to the second element of your list. Loop till head is past the last element (I have those pointed to NULL, not head) by incrementing both head and tail by one. If at any point tail > head, you have a loop.
What happens if you printf("%d",(int) c); at each iteration? I suspect that result->head is pointing to a node which is pointing to a member of the linked list, but is not in the linked list itself.
Potential test: Add a int seen to each member of the list and increment it on each member as you loop for a given number of nodes (something excessively high such as INT_MAX) and, when the loop stops, see if result->head->seen > 0:
typedef struct node {
term data;
struct node *next;
// to be removed later
int seen;
} node;
// place this before you get the infinite loop
unsigned int i = 1;
c->seen = 0;
do
{
c = c->next;
c->seen = i;
// replace INT_MAX with some number which is greater than the maximum list length
} while(++i <= INT_MAX);
// this should be roughly equal to i (might be off by 1).
// I'll bet it isn't though!
printf("result->head->seen = %d", result->head->seen);
One possible cause: you're never creating p2. Are you missing a line like this in your main function:
poly_create(&p2);
?