Program quits out after running? - c

The program runs fine and displays the data I want but then crashes. I don't think it is a memory leak from the linked list because I've tried many ways to free it and none have worked.
#include "Buildings.h"
void displayBuilding(struct node *x){
printf("Building Name: %s\n\tFloors: %d\n\tValue: %d\n\n", x->payload.name, x->payload.floors, x->payload.value);
if(x->last!=1){
displayBuilding(x->next);
}
}
void insert(struct node *x, char str[50]){
srand(t);
int f = (rand() % 6)+1;
int v = ((rand() % 20)+1)*f;
//printf("Floors: %d and Value: %d\n", f, v);
strcpy(x->payload.name, str);
x->payload.floors = f;
x->payload.value = v;
srand(time(NULL));
t+=f+v*(rand()%1000);
}
FILE* openData(FILE *f){
f = fopen("Buildings-Data.txt", "r");
if(f==NULL){
printf("No File!");
return 0;
}
return f;
}
void freeList(struct node* head)
{
struct node* tmp;
while (head != NULL)
{
tmp = head;
head = head->next;
free(tmp);
}
}
int main(){
FILE *f1;
struct node *head;
struct node *curr;
head = malloc(sizeof(struct node));
curr = malloc(sizeof(struct node));
curr = head;
int i;
for(i=0;i<9;i++){
curr->next = malloc(sizeof(struct node));
curr = curr->next;
}
f1 = openData(f1);
curr = head;
int readNum;
char trash;
fscanf(f1, "%d", &readNum);
fscanf(f1, "%c", &trash);
for(i=0;i<readNum;i++){
char str[50];
fscanf(f1, "%s",str);
insert(curr, str);
curr->last = 0;
if(readNum-i==1){
curr->last = 1;
}else{
curr = curr->next;
}
}
fscanf(f1, "%c", &trash);
fclose(f1);
curr = head;
printf("\n");
displayBuilding(curr);
curr = head;
freeList(head);
return 0;
}
My header file:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
struct building{
char name[50];
int floors;
int value;
};
typedef struct building place;
struct node{
place payload;
struct node *next;
int last;
};
int t = 500;

The problem is that when you create the linked list, you never set next to NULL in the last node of the list. You need to do that after the loop:
for(i=0;i<9;i++){
curr->next = malloc(sizeof(struct node));
curr = curr->next;
}
curr->next = NULL;
Because of this, the while (head != NULL) loop in freeList() never stops, and eventually tries to free the uninitialized pointer in the last node of the list.

Related

Reverse Every K Nodes

Every k nodes form a segment. If the last few nodes are less than K, then you can ignore them.
Write a reverseKnodes() which reserves every segment in the linked list.
The function prototype is given as follow: void reversekNodes(ListNode** head, int k);
Input format:
The 1st line is the k
The 2nd line is the data to create the linked list and ends with a non-digit symbol Example:
Input: 3 1 2 3 4 5 6 7 8 9 10 a
Output: 3 2 1 6 5 4 9 8 7 10
#include <stdio.h>
#include <stdlib.h>
struct _listNode
{
int item;
struct _listNode *next;
};
typedef struct _listNode ListNode;
void printList (ListNode * head);
void deleteList (ListNode ** ptrHead);
void reverseKNodes (ListNode ** head, int K);
int
main ()
{
ListNode *head = NULL, *temp;
int i = 0;
int K = 0;
scanf ("%d", &K);
while (scanf ("%d", &i))
{
if (head == NULL)
{
head = (ListNode *) malloc (sizeof (ListNode));
temp = head;
}
else
{
temp->next = (ListNode *) malloc (sizeof (ListNode));
temp = temp->next;
}
temp->item = i;
}
temp->next = NULL;
reverseKNodes (&head, K);
printList (head);
deleteList (&head);
return 0;
}
void
printList (ListNode * head)
{
while (head != NULL)
{
printf ("%d ", head->item);
head = head->next;
}
printf ("\n");
}
void
deleteList (ListNode ** ptrHead)
{
ListNode *cur = *ptrHead;
ListNode *temp;
while (cur != NULL)
{
temp = cur->next;
free (cur);
cur = temp;
}
*ptrHead = NULL;
}
void
reverseKNodes (ListNode ** head, int K)
{
struct _listNode *reverse (struct _listNode *head, int k){
if (!head)
return NULL;
struct _listNode* cur = head;
struct _listNode* next = NULL;
struct _listNode* prev = NULL;
int count = 0;
while (cur != NULL && count < K)
{
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
count++;
}
if (next != NULL)
head->next = reverse(next, K);
return prev;
}
}
I am not allowed to change anything else other than the void function for reverseKNodes and I know I have done it wrong but I dont know where I went wrong. Could someone help me please?
A few issues with nested functions ...
Nested functions aren't standard C.
Are of limited benefit.
They add extra overhead to invoke.
So [please] don't use them.
And, your usage of one is incorrect. In reverseKNodes, you define reverse but never call it. So, reverseKNodes is a no-op.
So, to fix, move reverse out of the body of reverseKNodes and place it above. Then, actually invoke it in reverseKNodes:
void
reverseKNodes(ListNode **head, int K)
{
*head = reverse(*head, K);
}
Here is the full refactored code. For aid in debug (e.g. with gdb), I added code to allow the program to take an input file as an argument.
#include <stdio.h>
#include <stdlib.h>
struct _listNode {
int item;
struct _listNode *next;
};
typedef struct _listNode ListNode;
void printList(ListNode *head);
void deleteList(ListNode **ptrHead);
void reverseKNodes(ListNode **head, int K);
int
main(int argc,char **argv)
{
ListNode *head = NULL, *temp;
int i = 0;
int K = 0;
--argc;
++argv;
FILE *xf;
do {
if (argc != 1) {
xf = stdin;
break;
}
xf = fopen(*argv,"r");
if (xf != NULL)
break;
perror(*argv);
exit(1);
} while (0);
fscanf(xf,"%d", &K);
while (fscanf(xf,"%d", &i)) {
if (head == NULL) {
head = (ListNode *) malloc(sizeof(ListNode));
temp = head;
}
else {
temp->next = (ListNode *) malloc(sizeof(ListNode));
temp = temp->next;
}
temp->item = i;
}
temp->next = NULL;
reverseKNodes(&head, K);
printList(head);
deleteList(&head);
return 0;
}
void
printList(ListNode *head)
{
while (head != NULL) {
printf("%d ", head->item);
head = head->next;
}
printf("\n");
}
void
deleteList(ListNode **ptrHead)
{
ListNode *cur = *ptrHead;
ListNode *temp;
while (cur != NULL) {
temp = cur->next;
free(cur);
cur = temp;
}
*ptrHead = NULL;
}
struct _listNode *
reverse(struct _listNode *head, int K)
{
if (! head)
return NULL;
struct _listNode *cur = head;
struct _listNode *next = NULL;
struct _listNode *prev = NULL;
int count = 0;
while (cur != NULL && count < K) {
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
count++;
}
if (next != NULL)
head->next = reverse(next, K);
return prev;
}
void
reverseKNodes(ListNode **head, int K)
{
*head = reverse(*head, K);
}
Here is the program output:
3 2 1 6 5 4 9 8 7 10

Segmentation fault when accessing strings from linked list

I am trying to write a program that counts how many times a word is used in a text document. To do this I created a function called wordList that creates a linked list with a node for each word. Unfortunately, whenever I try to read a word from the linked list with printf there is a segmentation fault. I believe this is because the linked list is not actually copying any of the words. I am wondering how I can resolve this issue. At the moment I do not know how to proceed. Thanks:)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
struct Node {
int timesUsed;
char* word;
struct Node* next;
};
struct Node* wordList(FILE *fp, struct Node* head);
struct Node* createNode(struct Node* head, char* word);
char* title(char* file);//creates file name based on command line input
int main(int argc, char** argv){
//Access file information---------------------------------------------
FILE *fp;
char* fileName = title(argv[1]);
fp = fopen(fileName, "r");
//Define Head node--------------------------------------------------------
struct Node* head = (struct Node*)malloc(sizeof(struct Node));
if (head == NULL){
printf("there is not enough memory on your device to continue\n");
}
//Access words--------------------------------------------------------
head = wordList(fp, head);
printf("%s\n",head->word);
free(head);
free(fileName);
return 0;
}
//Function that is causing problems==================================
struct Node* wordList(FILE *fp, struct Node* head){
char c;
char wordHolder[1240];//characters
int j = 0;
int count = 0;
do{
c = getc(fp);
printf("%c\n",c);
if(isalpha(c) || isdigit(c) || c == '\''){
wordHolder[j] = c;
j++;
}
else{
if(count){
char* tempWord = strdup(wordHolder);
head->word = tempWord;
head->timesUsed = 1;
head->next = NULL;
count = 1;
j = 0;
for(i = 0; i< strlen(wordHolder); i++){
wordHolder[i] = '\0';
}
}
else{
head = createNode(head, wordHolder);
j = 0;
for(i = 0; i< strlen(wordHolder); i++){
wordHolder[i] = '\0';
}
}
}
}
while(c != EOF);
return head;
}
//Creates a new node at end of list=====================================
struct Node* createNode(struct Node* head, char* word){
struct Node* temp = head;
while(temp != NULL){
temp = temp->next;
}
temp = (struct Node*)malloc(sizeof(struct Node));
temp->timesUsed = 1;
char* tempWord = strdup(word);
temp->word = tempWord;
temp->next = NULL;
return head;
}
//Creates fileName======================================
char* title(char* file){
char nameOfFile[500];
strcpy(nameOfFile, file);
strcat(nameOfFile, ".txt");
char* temp;
temp = strdup(nameOfFile);
if(temp == NULL){
printf("Your computer has litte memory.\n");
}
return temp;
}

Inserting different strings read from file in a linked list

I'm writing a programm in c that reads words from a file, and adds the different from them in a linked list. However, i don't get the right result.I have problem finding if a word exists in the list. Any help could be appreciated.Thanks.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct list_el {
char val[30];
struct list_el * next;
};
typedef struct list_el item, item2;
void main() {
item * curr, * head, * curr2, * head2;
FILE *fp;
char words[30];
int i;
head = NULL;
head2 = NULL;
if ((fp=fopen("file.txt","r"))==NULL)
printf("cannot open file\n");
i=0;
while (fscanf(fp,"%s",&words)!=EOF) {
if (i!=0)
while(curr2) {
if (!strcmp(words,curr2->val)){
break;
}
curr2 = curr2->next ;
}
if (curr2==0 || i==0){
curr = (item *)malloc(sizeof(item));
curr2 = (item2 *)malloc(sizeof(item2));
strcpy(curr->val,words);
strcpy(curr2->val,words);
curr->next = head;
curr2->next = head2;
head = curr;
head2 = curr2;
}
i++;
}
while(curr) {
printf("%s\n", curr->val);
curr = curr->next ;
}
fclose(fp);
}
int main(void) {//void main() is invalid.
item *curr, *head = NULL;
FILE *fp;
char words[30];
if ((fp=fopen("file.txt","r"))==NULL){
printf("cannot open file\n");
return EXIT_FAILURE;//can't continue
}
while (fscanf(fp,"%29s", words) != EOF) {//remove &
curr = head;
while(curr) {//Search the current list
if (!strcmp(words, curr->val)){
break;
}
curr = curr->next;
}
if (curr == NULL){//not find words
item *node = malloc(sizeof(*node));
strcpy(node->val, words);
node->next = head;
head = node;
}
}
fclose(fp);
curr = head;
while(curr) {
printf("%s\n", curr->val);
curr = curr->next ;
}
}

Segfault when trying to sort a linked list of names by bubble sorting

I am trying to sort a linked list in alphabetical order using bubble sort, but I am getting a segfault when I run the program. I can print off the names before sorting, but when I sort them and try to display them, it doesn't work.
Here is the code that I have and the output I want is to just display the names in order.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MAX_STR_LEN 25
typedef struct Data_ {
char *name;
struct Data_ *next;
} Data;
Data* bubble_sort(Data *list);
Data* read_from_file(const char *file, const int size);
void display(Data *list);
void push(Data **head, char *name);
int main(int argc, char **argv) {
if(argc != 2){
printf("Not enough parameters!");
exit(0);
}
Data *head = NULL;
int size = 10;
head = read_from_file(argv[1], size);
printf("\nBefore sort");
display(head);
printf("\nBubble Sort\n");
head = bubble_sort(head);
display(head);
}
Data* bubble_sort(Data *head) {
int count = 0, i;
Data *start = head;
Data *curr = NULL;
Data *trail = NULL;
Data *temp = NULL;
//grab the count
while(start != NULL) {
count++;
start = start->next;
}
for( i = 0; i < count; ++i) {
curr = trail = head; //set curr and trail at the start node
while(curr->next != NULL){
if(strcmp(curr->name, curr->next->name) > 0) {
temp = curr->next;
curr->next = curr->next->next;
temp->next = curr;
if(curr==head)
head = trail = temp;
else
trail->next = temp;
curr = temp;
}
trail = curr;
curr = curr->next;
}
}
return head;
}
void push(Data **head, char *name) {
Data *temp = malloc(sizeof(Data));
temp->name = strdup(name);
temp->next = *head;
*head = temp;
}
Data* read_from_file(const char *file, const int size) {
FILE *input;
input = fopen(file, "r");
Data *new_ = (Data*)malloc(sizeof(Data*));
new_->next = NULL;
int i;
char name[MAX_STR_LEN];
for(i = 0; i < size; i++) {
fscanf(input, "%24s", &name);
push(&new_, name);
}
return new_;
}
void display(Data *list) {
Data *current = list;
while(current->next != NULL) {
printf("\n%s", current->name);
current = current->next;
}
}
The list of names that I read in is
Derek
Drew
Randell
Terrell
Carmen
Colin
Eddy
Pablo
Lamont
Dexter
In addition to the problem pointed out by BLUEPIXY there were a couple of other problems in the code. I tested this and it seems to work.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MAX_STR_LEN 25
typedef struct Data_ {
char *name;
struct Data_ *next;
} Data;
Data* bubble_sort(Data *list);
Data* read_from_file(const char *file);
void display(Data *list);
void push(Data **head, char *name);
int main(int argc, char **argv) {
if(argc != 2){
printf("Not enough parameters!");
exit(0);
}
Data *head = NULL;
head = read_from_file(argv[1]);
printf("\nBefore sort");
display(head);
printf("\nBubble Sort\n");
head = bubble_sort(head);
display(head);
}
Data* bubble_sort(Data *head) {
int i = 1;
Data *curr = NULL;
Data *trail = NULL;
Data *temp = NULL;
Data *after = NULL;
while( i == 1) { // keep sorting
i = 0; // if not changed loop will exit
curr = trail = head; //set curr and trail at the start node
while(curr->next != NULL){
if(strcmp(curr->name, curr->next->name) > 0) {
i = 1; // still sorting
after = curr->next;
temp = after->next; // temp may be NULL. thats ok
after->next = curr;
curr->next = temp;
if(curr==head) {
head = after;
}
else {
trail->next = after;
}
curr = after;
}
trail = curr;
curr = curr->next;
}
}
return head;
}
void push( Data **head, char *name) {
Data *temp = malloc(sizeof(Data));
temp->name = strdup(name);
temp->next = *head;
*head = temp;
}
Data* read_from_file(const char *file) {
FILE *input;
Data *new_ = NULL; // allocation will take place in push
input = fopen(file, "r");
char name[MAX_STR_LEN];
while( fscanf(input, "%24s", name) == 1) { // scan until scan fails to return one value
push( &new_, name);
}
return new_;
}
void display(Data *list) {
Data *current = list;
while(current != NULL) {
printf("\n%s", current->name);
current = current->next;
}
}

C program reversed linked list

Im trying to write a program in c that adds big numbers with linked list. I used reverse to add the numbers, but i cant get it to reverse again. It should be used several times(iow, looped to ask numbers until exit)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "function.c"
int main()
{
char n1[500];
int lenSum, len;
printf("Welcome! \nThis program performs addition of big whole numbers that can contain upto a maximum of 500 digits.");
printf("\nEnter first number: ");
scanf("%s", n1);
len = strlen(n1);
node *root = create(n1[0]);
node *head = root;
root, head = createList(n1,root,head,len);
root=head;
printf("Enter second number: ");
scanf("%s", n1);
len = strlen(n1);
node *root2 = create(n1[0]);
node *head2 = root2;
root2, head2 = createList(n1,root2,head2,len);
root2=head2;
root=head;
printf("\nYour first number is:\t ");
while(root!=NULL){
printf("%d\t",root->digit);
root=root->next;
}
root2=head2;
printf("\nYour second number is: ");
while(root2!=NULL){
printf("%d\t",root2->digit);
root2=root2->next;
}
printf("\nCalculating sum:\n");
root=head;
root2=head2;
node *sum = create('0');
node *headSum = sum;
sum,headSum = addIntegers(root, root2, sum, headSum);
printf("\nThe sum is : ");
sum=headSum;
while(sum->next!=NULL){
printf("%d",sum->digit);
sum=sum->next;
}
printf("\n");
sum = headSum;
printf("\nThe number ");
saveResult(sum);
printf("has been saved in the file 'results.txt'\n");
root, head = reverseLinkedList(sum, headSum);
printDigit(root);
root=head;
printf("\n\n\t ");
while(root!=NULL){
printf("%d\t",root->digit);
root=root->next;
}
free(root);
free(root2);
//free(sumDigit);//
return 0;
}
function.h:
#ifndef function.h
#define function.h
typedef struct node {
int digit;
struct node *next;
}node;
node* create(char digit);
node* createList(char number[500], node* root,node* head, int length);
node* addIntegers(node* root, node* root2, node* sum, node* headSum);
#endif
function.c:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "function.h"
node* createList(char number[500], node* root,node* head, int length){
int i;
i=0;
for(i=1;i<=length-1;i++) {
root = (node *)malloc(sizeof(node));
root->digit = number[i]-'0';
root->next = head;
head = root;
}
return root, head;
}
void printDigit(node* root){
while(root!=NULL){
printf("%d",root->digit);
root=root->next;
}
}
node* addIntegers(node* root, node* root2, node* sum, node* headSum){
int carry = 0;
int sumDigit = 0;
while((root!=NULL || root2!=NULL)) {
if (root==NULL || root2==NULL){
if (root == NULL){
sumDigit=root2->digit +carry;
root2=root2->next;
goto add;}
if (root2 == NULL){
sumDigit = root->digit + carry;
root=root->next;
goto add;
}
}
else{
sumDigit = root->digit + root2-> digit + carry;
}
root2 = root2->next;
root = root->next;
add:
sum = (node *)malloc(sizeof(node));
sum->digit = sumDigit%10;
sum->next = headSum;
headSum = sum;
if (sumDigit > 9){
carry = 1;}
else{
carry = 0;
}
}
if (carry == 1){
sum = (node *)malloc(sizeof(node));
sum->digit = 1;
sum->next = headSum;
headSum = sum;
}
return sum, headSum;
}
node* create(char digit)
{
node *root = (node *) malloc( sizeof(node));
if (root == NULL){
printf("ERROR\n");
exit(1);
}
root->digit = digit-'0';
root->next = NULL; //default is null
return root;
}
void saveResult(struct node *sum)
{
FILE * fp = fopen ("result.txt", "w+");
while(sum->next != NULL)
{
printf("%d", sum->digit);
fprintf(fp, "%d", sum->digit);
sum = sum->next;
}
fclose(fp);
printf(" ");
}
node* reverseLinkedList(node *root, node* head){
node* reversed = create(root->digit);
node* reversedTail = reversed;
while(root!=NULL){
//printf("%d", root->digit);
root = root->next;
reversed->digit = root;
reversed->next =head->next;
reversed = reversed->next;
head = root;
}
reversed = reversedTail;
return reversed, reversedTail;
}
As the question is not very specific with the issue you're are facing, below are some points to be taken care,
In function reverse(),
return reversed, reversedTail; will always return reversedTail.
You are trying to call this function from main() as
root, head = reverseLinkedList(sum, headSum); which again head will get the return values. This is incorrect. Usually you should be using a assignment to one member at a time.
link list reverse sample like this
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int digit;
struct node *next;
} node;
node *reverse_copy(node *list){
node *new_list = NULL;
while(list){
node *new_node = malloc(sizeof(node));
new_node->digit = list->digit;
new_node->next = new_list;
new_list = new_node;
list = list->next;
}
return new_list;
}
void reverse_not_copy(node **header){
node *tmp, *list, *newList = NULL;
if (header==NULL || *header == NULL) return;
list = *header;
while(list != NULL){
tmp = list;
list = list->next;
tmp->next = newList;
newList = tmp;
}
*header = newList;
}
void print(node *head){
while(head){
printf("%d ", head->digit);
head = head->next;
}
printf("\n");
}
int main(void){
node *np;
node n[3] = { {1,NULL}, {2, NULL}, {3, NULL}};
n[0].next = &n[1];
n[1].next = &n[2];
print(&n[0]);//1 2 3
np=reverse_copy(&n[0]);
print(np);//3 2 1
reverse_not_copy(&np);
print(np);//1 2 3
return 0;
}

Resources