lunar soap5
lunar soap5

Reputation: 11

Segmentation fault (core dumped)

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

Answers (2)

husin alhaj ahmade
husin alhaj ahmade

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

Tibrogargan
Tibrogargan

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

Related Questions