c - 检查指针时出现段错误

标签 c segmentation-fault

<分区>

我正在编写一个读取字典文件(文本文件,每行一个单词)的程序,并将其插入到一个由数组“链表”组成的结构中,其中单词递归转发到 [第一个字母- 'a'] 数组的条目(这是另一个数组,处理下一个字母)。当整个单词被“消耗”时,它将单词(未更改)插入到规则的单词链表中。该程序成功处理了前 15 个单词,但在第 16 个单词时抛出段错误。

看起来段错误发生在以下代码段中的 add() 方法中:

struct LinkedList * new = (struct LinkedList *) calloc(1,
                                       sizeof(struct LinkedList));
            if (!new) {
                perror("Not enough memory!"); // Error here
                exit(2);
            }

(希望如此)相关代码:

void addList (struct LinkedList * list, char * word) {
    if (!list->next)
    {
        struct LinkedList * new = malloc(sizeof(struct LinkedList));
        if (!new) {
            perror("Not enough memory!");
            exit(2);
        }

        char * new_word = malloc(strlen(word) * sizeof(char));
        if (!new_word) {
            fprintf(stderr, "Not enough memory!");
            exit(2);
        }


        new->next = 0;
        strcpy(new_word, word);
        new->word = new_word;
        list->next = new;
    }
    else
    {
        addList(list->next, word);
    }
}


void add(struct HashTree * root, char * word, char * word_sorted, int length) {

    if (length == 0)                                     // Found the correct place
    {

        if (!root->words)                                // If words are not allocated
        {
            // Create list node
            struct LinkedList * new = calloc(1, sizeof(struct LinkedList));
            if (!new) {
                perror("Not enough memory!");
                exit(2);
            }

            char * new_word = malloc(strlen(word) * sizeof(char));
            if (!new_word) {
                fprintf(stderr, "Not enough memory!");
                exit(2);
            }

            new->next = 0;

            strcpy(new_word, word);

            new->word = new_word;
            root->words = new;
        }   

        else                                            // Add to the Linked List
        {
            addList(root->words, word);
        }
    }

    else 
    {
        // printf("Length_add = %d\n", length);
        if (!root->next)                                 // If the array was not allocated yet
        {

            struct HashTree * new = malloc(27 * sizeof(struct HashTree *));
            if (!new) {
                perror("Not enough memory!");
                exit(2);
            }


            root->next = new;
        }


        add(&(root->next[ word_sorted[0] - 'a' ]), 
            word, (char *) (word_sorted +1), (length-1));  // Use the next letter.

    }


}

为了节省空间,Here is the link to the full code.

这是 gdb 核心和回溯的输出:

    Program terminated with signal SIGSEGV, Segmentation fault. 

100 perror("Not enough memory!"); 

Full GDB output

我之前用Java实现过类似的算法,算法好像是对的。我是 C 的新手,不明白可能出了什么问题。如果有任何帮助,我将不胜感激!

编辑: 删除了 sort、clean 和 cleanWords 方法(它们对向结构中添加单词影响不大)。处理第二个词时发生分割,第 125 行:

perror("Dictionary file not found!");

Link to code -
Link to sample dictionary

Valgrind output

最佳答案

add() 的主要 else 子句中,您分配了一些内存,但不对其进行初始化。然后在下一次对 add() 的递归调用中使用未初始化的内存。至少,使用 calloc() 代替 malloc()。您也只分配了足够的空间用于 27 个指向您的结构的指针,但您使用它就像分配了 27 个结构一样。

错误:

struct HashTree * new = malloc(27 * sizeof(struct HashTree *));

右:

struct HashTree *new = calloc(27, sizeof(struct HashTree));

或者:

struct HashTree *new = calloc(27, sizeof(*new));

此外,在 addList()add() 中,您没有为字符串分配足够的空间;你忘记了尾随的 null。

错误:

char *new_word = (char *) malloc(length * sizeof(char));

右:

char *new_word = (char *) malloc(length + 1);

我不在我的 C 代码中使用 C++ 关键字,所以我会使用 new_hash 或类似的东西,而不仅仅是 new。许多人会因为分配上的强制转换而责备你。

通过这些更改,代码对我来说运行完成了。它像愤怒一样泄漏,但这完全是预料之中的。

关于c - 检查指针时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35121032/

相关文章:

c++ - 指向字符串的指针在函数中如何工作?

C fscanf 段错误错误 "No source available for "fancyfile() at 0x7fff855e6d39"

c++ - 在看似简单的操作上导致 vector<int> 中的 push_back 出现段错误

c - 为什么我不能在用 C 编写的 tcp 客户端/服务器中正确接收非纯文本文件?

c - 什么是 C 中传递的 byValue 和 byReference 参数?

c - 结束子进程而不返回值

c - 将输入字符串放入数组并按字母顺序对字符串数组进行排序

python - mysql c 的 ctypes 错误

c - 我无法解决 "segmentation fault: 11"

c - 为什么这段代码会导致段错误?