Reputation: 11
I'm working on a code in my class and it looks good, but when I go to compile it, it compiles, but when I enter a string, I get the error: Segmentation fault (core dumped). My goal is to be able to sort strings alphabetically. Below is my code and any help is appreciated:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct wNode {
char aWord[16];
struct wNode *last;
struct wNode *next;
} wNode;
wNode *getFreeNode(wNode **freeList) {
wNode *freed = *freeList;
if(freed != (wNode *) NULL)
*freeList = freed->next;
return freed;
}
wNode *deleteWord(char *word, wNode *head) {
wNode *here = head->next;
while((here != head) && (strcmp(word, here->aWord) != 0))
here = here->next;
if(here != head) {
here->next->last = here->last;
here->last->next = here->next;
}
else
printf("Word not found.\n");
}
int main(int argc, char *argv[]) {
wNode listNodes[100]; // creates doubly linked list
wNode *freeNodes; // amount of free nodes
wNode *headNode; // initialize head node
wNode *newNode;
wNode *thisOne;
wNode *thatOne;
char stop[6] = "!stop"; // command to stop taking strings
char userInput[100];
int i;
// initializes the head node
headNode = listNodes;
headNode->next = headNode;
headNode->last = headNode;
strcpy(headNode->aWord, "HEADNODE");
//initializes new node
newNode = listNodes;
newNode->aWord[0] = '\0';
newNode->next = (wNode *) NULL;
newNode->last = (wNode *) NULL;
// initializes thisOne for searching through the doubly linked list
thisOne = listNodes + 1;
freeNodes = thisOne;
for(i = 1; i < 99; i++) {
thisOne->aWord[0] = '\0';
thisOne->next = thisOne + 1;
thisOne->last = (wNode *) NULL;
thisOne = thisOne + 1;
}
thisOne->next = (wNode *) NULL;
thisOne->last = (wNode *) NULL;
thisOne->aWord[0] = '\0';
while(-1) {
// prompts user to enter strings
printf("Enter a string: ");
scanf("%f", userInput);
// checks if user wants to stop adding strings and breaks out of loop
if(strcmp(stop, userInput) == 0)
break;
/* Checks if user wants to delete a string.
* If string is not found in the list, then it prints out that
* the word was not found. */
else if(*userInput == '~') {
userInput[16] = '\0';
thisOne = headNode->next;
while((thisOne != headNode) && (strcmp((userInput + 1), thisOne->aWord) != 0))
deleteWord(userInput, headNode);
}
// handles insertion of strings
else {
thisOne = headNode->next;
while((thisOne == headNode) && (strcmp(userInput, thisOne->aWord) >= 0))
thisOne = thisOne->next;
newNode = getFreeNode(&freeNodes);
if(newNode == (wNode *) NULL) { // checks if there are any free nodes in listNodes
printf("Error: no free nodes!\n");
return -1;
}
if(strlen(userInput) > 16) // checks if userInput has over 16 chars
userInput[15] = '\0'; // truncates userInput
strcpy(newNode->aWord, userInput);
newNode->next = thisOne;
newNode->last = thisOne->last;
thisOne->last = newNode;
newNode->last->next = newNode;
}
}
thisOne = headNode->next;
while(thisOne != headNode) {
printf("%f ", thisOne->aWord);
thisOne = thisOne->next;
}
printf("\n\n");
thisOne = headNode->last;
while(thisOne != headNode) {
printf("%f ", thisOne->aWord);
thisOne = thisOne->last;
}
printf("\n");
return 0;
}
Upvotes: 0
Views: 196
Reputation: 481
Try debugging. Use gdb under terminal and set a break point at main function and step over each instruction like this
gcc -g filename.c
gdb a.out
..................
Now , set the breakpoint
break main
then ... Run your program by typing run command ( when it reaches breakpoint, it will stop. Then execute single instruction like this
run
n
do this until the segmentation fault occurs, then check the corresponding instruction. You will be able to find the instruction which causes SIGSEGV.
Upvotes: 1
Reputation: 4603
This piece of code:
// initializes the head node
headNode = listNodes;
headNode->next = headNode;
Sets headNode and headNode-> next to valid objects, fine. But then this:
//initializes new node
newNode = listNodes;
newNode->aWord[0] = '\0';
newNode->next = (wNode *) NULL;
Implicitly changes headNode->next
to NULL
, so when a user enters a string, this code:
// handles insertion of strings
else {
thisOne = headNode->next;
sets thisOne
to NULL
, and then a few lines later this code:
newNode->next = thisOne;
newNode->last = thisOne->last;
dereferences thisOne
, which is NULL
Upvotes: 1