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
typedef struct{
int *sols;
int rest;
int fitness;
int num;
struct lista* next;
}lista;
lista* gere_lista(lista *solucoes, int *sol, int *grafo, int objs, int rests){
int i;
int *nova_sol;
lista *temp = solucoes;
nova_sol = malloc(sizeof(int)*objs);
nova_sol = update_sol(sol, nova_sol, objs);
for(i=0; i<objs; i++){
nova_sol = gera_vizinho3(nova_sol, i);
temp->sols = malloc(sizeof(int)*objs);
temp->sols = update_sol(nova_sol, temp->sols, objs);
temp->rest = calcula_restricoes(nova_sol, grafo, objs, rests);
temp->fitness = calcula_max(nova_sol, grafo, objs);
temp->num = i;
temp = temp->next;
}
return solucoes;
}
int* pesquisa_tabu(int sol[], int *grafo, int objs, int rests, int num_iter){
int fitness, fitness_viz, i, memoria[objs*2/8];
lista *solucoes, *temp;
solucoes = malloc(sizeof(lista));
temp = solucoes;
for(i=1; i<objs; i++){
temp->next = malloc(sizeof(lista));
}
temp->next = NULL;
solucoes = gere_lista(solucoes, sol, grafo, objs, rests);
return sol;
}
I'm trying to do a tabu search algorithm to my school assignment, but it's not really working.
This code is supposed to create a linked list with the same number of links as the objects that are in the pesquisa_tabu function, then it generates the same number in neighbors and add one neighbor to each link, to then process all the information in the pesquisa_tabu function.
And i can't find what is wrong in this code, it is always crashing on the second iteration...
for(i=1; i<objs; i++){
temp->next = malloc(sizeof(lista));
}
temp->next = NULL;
What you have done is allocated memory for objs number of lista's and lost links to all of them because you are always making temp->next point to a new memory and then later making it point to NULL.You need to maintain a head of the list while allocating memory for all nodes.
lista *solucoes, *temp;//solucoes will act as head of list
temp = NULL;
solucoes = NULL;
for(i=1; i<objs; i++)
{
if(solucoes==NULL)
{
temp = malloc(sizeof(lista));
solucoes = temp;
}
else
{
temp->next = malloc(sizeof(lista));
temp = temp->next;
}
}
temp->next = NULL;
Related
I am currently working on a program which is meant to hold inventory for a watercraft rental company. This program uses a linked list to hold the data about the inventory. I have gotten all of the functions to work other than print by price. This function is meant to sort the linked list in order of lowest to highest price and then print the list. I think that my sorting algorithm is alright but I am getting a seg fault that I can not find the cause of. Any help is appreciated. The following code is my print by price function.
//creates a new list and copies every number from inventory over to this one
//except add the values in order from lowest to highest by adding in order
int i = 0;
//initialize new list
list_t *sorted = (list_t*)malloc(sizeof(list_t));
sorted->size = list->size;
sorted->head = NULL;
sorted->tail = NULL;
//make temp variable for iteration
watercraft_t *init = list->head;
watercraft_t *temp = list->head;
watercraft_t *prev = NULL;
for(i = 0; i < list->size; ++i){
watercraft_t *new = (watercraft_t*)malloc(sizeof(watercraft_t));
new = init;
if(sorted->head == NULL){
new = sorted->head;
new->next = NULL;
}
else if(new->total_price < temp->total_price){
prev->next = new;
new->next = temp;
}
else if(temp->next == NULL){
temp->next = new;
new->next = NULL;
}
prev = temp;
temp = temp->next;
init = init->next;
}
This is the structure which is within the linked list holding the data
typedef struct watercraft {
char type[15]; // e.g. pontoon, sport boat, sailboat, fishing,
// canoe, kayak, jetski, etc.
char make[20];
char model[30];
int propulsion; // 0 = none; 1 = outBoard; 2 = inBoard;
char engine[15]; // Suzuki, Yamaha, etc.
int hp; // horse power
char color[25];
int length; // feet
double base_price;
double total_price;
accessories_t extras;
struct watercraft *next;
} watercraft_t;
If there is any other code that is necessary for this problem please let me know. There are about 400 more lines of code for this project.
I have this code and i want to print the tid of each node. I have segmatation fault in this for loop
printf("%d\n",tasks_head->head->tid); And i am not sure if the task_count[] works as i want. I want to save a counter++ in each position of the array.
struct Tasks
{
int tid;
int difficulty;
struct Tasks *next;
};
struct Head_GL
{
int tasks_count[3];
struct Tasks *head;
};
struct Head_GL *tasks_head=NULL;
int num=0;
int insert_task(int tid, int difficulty){
num++;
struct Tasks *prev=NULL;
struct Tasks *temp=NULL;
struct Tasks *new=(struct Tasks*)malloc(sizeof(struct Tasks));
tasks_head=(struct Head_GL*)malloc(sizeof(struct Head_GL));
tasks_head->head=(struct Tasks*)malloc(sizeof(struct Tasks));
tasks_head->tasks_count[0]=0;
tasks_head->tasks_count[1]=0;
tasks_head->tasks_count[2]=0;
tasks_head->head->difficulty=0;
tasks_head->head->tid=0;
tasks_head->head->next=NULL;
if(new==NULL)
return 0;
new->tid = tid;
new->difficulty = difficulty;
new->next = NULL;
if(difficulty==1)
tasks_head->tasks_count[0]++;
else if(difficulty==2)
tasks_head->tasks_count[1]++;
else
tasks_head->tasks_count[2]++;
if(tasks_head==NULL){
tasks_head->head = new;
return 1;
}
if( tasks_head->head->difficulty > difficulty){
new->next = tasks_head->head;
tasks_head->head= new;
return 1;
}
else{
prev = tasks_head->head;
temp = tasks_head->head->next;
while(temp != NULL && temp->difficulty < difficulty){
prev = temp;
temp = temp->next;
}
if(temp==NULL){
prev->next = new;
return 1;
}
else{
new->next = temp;
prev->next = new;
return 1;
}
}
}
int main(){
printf("hello1\n");
if(1==insert_task(1,1))
printf("alo");
if(1==insert_task(4,1))
printf("alo");
if(1==insert_task(3,2))
printf("alo\n");
printf("%d\n",num);
for(int i=0; i<num; i++){
printf("%d\n",tasks_head->head->tid);
tasks_head->head=tasks_head->head->next;
}
/*
for(int i=0; i<3; i++){
printf("%d",tasks_head->tasks_count[i]);
}*/
return 0;
}
There are a few problems with this code, but the most important is how you are affecting tasks_head.
At present you are malloc'ing a new tasks_head each time you enter insert_task, and recreating the head element, with these two lines:-
tasks_head=(struct Head_GL*)malloc(sizeof(struct Head_GL));
tasks_head->head=(struct Tasks*)malloc(sizeof(struct Tasks));
Normally you would either do this once, in a separate call to an initialisation function, or you can do it within insert_task by checking if it has already been performed.
You don't really need to create "head" separately, as the head will be the first "new" when you initialise the tasks_head global variable. So if you move this section of code down to below the creation of the "new" task, then you can assign it directly to the head.
If we look at the code where you are inserting the item into the linked list based upon its difficulty, then you can see that you are already doing this:-
if(tasks_head==NULL){
tasks_head->head = new;
return 1;
}
So the creation of a separate "head" is totally unnecessary.
The check here, by the way is exactly the check you would want to perform the once-off initialisation of "tasks_head", so if we take your code from above and move it into this section, then you will not keep reseting your global.
The downside of moving the initialisation, however, is that you've already tried to adjust the task difficulty count, so this also needs to come below, and we'll need to add an equivalent for the init case.
If you put all of those changes together you get the following:-
int insert_task(int tid, int difficulty){
num++;
struct Tasks *prev=NULL;
struct Tasks *temp=NULL;
struct Tasks *new=(struct Tasks*)malloc(sizeof(struct Tasks));
if(new==NULL)
return 0;
new->tid = tid;
new->difficulty = difficulty;
new->next = NULL;
if(tasks_head==NULL){
tasks_head=(struct Head_GL*)malloc(sizeof(struct Head_GL));
tasks_head->head=(struct Tasks*)malloc(sizeof(struct Tasks));
tasks_head->tasks_count[(difficulty != 1 && difficulty != 2)?2:difficulty-1]=1;
tasks_head->head = new;
return 1;
}
if(difficulty==1)
tasks_head->tasks_count[0]++;
else if(difficulty==2)
tasks_head->tasks_count[1]++;
else
tasks_head->tasks_count[2]++;
if( tasks_head->head->difficulty > difficulty){
new->next = tasks_head->head;
tasks_head->head = new;
return 1;
}
else{
prev = tasks_head->head;
temp = tasks_head->head->next;
while(temp != NULL && temp->difficulty < difficulty){
prev = temp;
temp = temp->next;
}
if(temp==NULL){
prev->next = new;
return 1;
}
else{
new->next = temp;
prev->next = new;
return 1;
}
}
}
The task_count difficulty mapping looks a little odd but I've tried to replicate your current behaviour, where a task of difficulty 1 is set to 0 and 2 is set to 1 and everything else is set to 2. I've done that with this slightly funky line using a tenery operator:
tasks_head->tasks_count[(difficulty != 1 && difficulty != 2)?2:difficulty-1]=1;
But it might just be that you want:
tasks_head->tasks_count[difficulty-1]=1;
if your task difficulty is only in the range 1-3.
Lastly we need to look at your loops in your main method which are currently modifying the global variable while trying to traverse the linked list.
for(int i=0; i<num; i++){
printf("%d\n",tasks_head->head->tid);
tasks_head->head=tasks_head->head->next;
}
I think you want to think about using a pointer to traverse this like the following:-
for(struct Tasks *p = tasks_head->head; p != NULL; p = p->next){
printf("%d\n", p->tid);
}
I'll leave you to think about the second loop to work out how you might wish to do something similar.
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
...
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
In order to understand tries I am creating this very simple C program that takes from user 10 nums from 0 to 9 as children of the trie. The final step is to print this nums with the function print, but I am getting a segmentation fault:
#include <stdio.h>
#include <stdlib.h>
typedef struct list
{
int data;
struct list *ar[10];
} list;
void insert(list *head);
void print(list *head);
int main(void)
{
printf("hello\n");
list *root = malloc(sizeof(list));
insert(root);
print(root);
}
void insert(list *head)
{
int a, i;
if (head == NULL) {
return;
}
for (i = 0; i < 10; i++) {
printf("Give Num 0-9\n");
scanf("%i", &a);
head->ar[a] = malloc(sizeof(head));
head = head->ar[a];
head->data = a;
}
}
void print(list *head)
{
if (head == NULL) {
return;
}
while (head != NULL) {
for (int i = 1; i < 10; i++) {
if (head->ar[i] != NULL) {
printf("%i", i);
head = head->ar[i];
break;
}
}
}
printf("\n");
}
There are several issues with your code:
The first mention of malloc doesn't actually initialize the memory (the ar field). You should initialize it properly
list *root = malloc(sizeof(list));
Is missing initialization, e.g.
root->data = 0;
for (size_t ii = 0; ii < 10; ii++) {
root->ar[ii] = NULL;
}
When you are actually gathering input, you allocate only enough memory for the pointer, not for the actual list itself.
head->ar[a] = malloc(sizeof(head));
should be initialized as above (head = malloc(sizeof(list)); for (size_t ...
There seems to be an infinite loop when actually running your program (after correcting all these issues).
EDIT: Remove calloc...
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!"