开发者社区 问答 正文

以链接列表的形式构建字典并出现分段错误(核心转储)错误

我知道分段错误(核心转储)错误是因为我试图访问我无权访问的内存,但我不明白为什么它会对我的程序造成影响。我确定问题出在printList(node *head)函数上,但我不明白为什么。

在这段代码中,我必须接受用户输入并以链接列表的形式创建字典。这是完整的代码:

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>

//To count the number of times an element was added to the dictionary
static int countWords=0;

typedef struct node{

    char string[255]; //store the data
    struct node *next; //pointer to the next structure -> this is a pointer

}node;

//Prints the list
void printList(node *head){

    node *p = head;

    do{
        for(int i=0; i<255; i++)
            printf("%c", p->string[i]);
        p = p -> next;
    }
    while(p->next != NULL);

}

//Inserts the word in alphabetical order in the list
node *insert_dictionary_order(char *pWord, node *dictionary){

    node *head = dictionary; //head of the first node
    node *temp = NULL; //Node that will be placed in the linked list
    node *p = NULL; //iterator 

    //creating individual isolated nodes -> not attached to a list
    temp = (node*)malloc(sizeof(node));

    //This stores the values that pointer gives us in an array
    char word[255];
    for(int i=0; i<5; i++)
        word[i] = *(pWord + i);

    //instantiating the node member
    temp->next = NULL;
    for(int i=0; i<5; i++)
        temp -> string[i] = word[i];

    //LinkedList is still empty
    if(head == NULL){
        printf("\nWe get here4!!\n");
        head = temp;
        printList(head); //THIS DOESNT WORK
        printf("\nWe get here5!!\n");
    }
    else{
        printf("\nWe get here6!!\n");
        p = head;
        //Comparing temp to words in the dictionnary
        //To know if we are at the first iteration (changing the head)
        do{

            printf("New word: %s\nDictionary Word: %s\n", temp -> string, p->string);

            if(strcmp(temp->string, p->string) < 0 && countWords ==0){ //Special case for the head
                temp -> next = p;
                head = temp;
                countWords++;           
            }
            //Checking if we are at inserting position
            else if(strcmp(temp->string, p->string) > 0 && strcmp(temp->string, (p->next)->string) < 0){
                temp->next = p->next;
                p->next = temp;
                countWords++;
            }

            p = p->next;                
        }
        while(p->next != NULL);
    }
    printList(head);
    return head;
}

//To check if a certain character is a letter
int isALetter(char c){

    if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || 
    c == '\0')
        return 1;
    else
        return 0;
}

int main(){

    node *dictionary = NULL;

    //Prompting the user to enter strings
    printf("Please enter some strings.\n");

    //To store the strings that the user enters 
    char string[10000];
    fgets(string, 10000, stdin);

    //Putting the string to lower case for easy manipulations
    for(int i=0; i<10000; i++)
        string[i] = tolower(string[i]);

    //To put the word in an array
    char word[255];
    //looping through the strings
    int i=0;
    //looping through the word
    int j = 0;

    //Checking the strings to put the words in the dictionnary
    do{
        //Checking if we need to escape the loop
        if(i>0 && ((string[i] == '.' && string[i-1]== ' ' )|| string[i] == 0))
            break;

        //Checking if a letter
        if(isALetter(string[i]) == 0){
            i++;
            continue;
        }   

        //Checking if end of the word
        if(isALetter(string[i+1]) == 0)
        {       
            word[j] = string[i];

            printf("\n");
            char *pWord;
            pWord = word;

            printf("\nWe get here1!!\n");
            //Adding word to the dictionary
            dictionary = insert_dictionary_order(pWord, dictionary);

            //***trying stuff
            printf("\nWe get here2!!\n");

            //***Printing the updated linked list
            //printList(dictionary);    

            //***trying stuff
            printf("\nWe get here3!!\n");

            //reseting the word array
            memset(word, 0, 255);   

            j = 0;
            i++;
            continue;
        }
        word[j] = string[i];
        j++;
        i++;
    }
    while(i != 10000);

    //Printing the list
    printf("\n\nPrinting the list..\n\n");

    printList(dictionary);


    return 0;
}
这是输出:

Please enter some strings.
zz aa


We get here1!!

We get here4!!
Segmentation fault (core dumped)

我们可以清楚地看到问题出在printList(node *head)带有此输出的方法上,因为“我们到这里了!” 数字2、3、5和6不会出现(它们全都在调用此方法之后)。

展开
收起
kun坤 2019-11-29 11:38:06 488 分享 版权
1 条回答
写回答
取消 提交回答

  • do{ p = p -> next;} while(p->next != NULL);。那可能是您问题的根源。到while检查条件时,p上一次迭代的值将为NULL。您的代码中还有其他问题。

    请使用调试器。如果这样做,您会看到以下内容:
    
    Please enter some strings.
    aa zz
    
    
    We get here1!!
    
    We get here4!!
    
    Program received signal SIGSEGV, Segmentation fault.
    0x0000555555555334 in printList (head=0x612000000040) at t.c:26
    26          while(p->next != NULL);
    (gdb) p p
    $1 = (node *) 0x0
    
    2019-11-29 11:38:40
    赞同 展开评论
问答地址: