简体   繁体   English

Segmentation fault:打印“Dictionary”内容时出现11

[英]Segmentation fault: 11 occurs when printing the contents of “Dictionary”

I've been trying to create a dictionary of words and their definitions(sort of Oxford English Dictionary).我一直在尝试创建一个单词词典及其定义(类似于牛津英语词典)。 So far, I've finished half of the job:到目前为止,我已经完成了一半的工作:

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

typedef struct{

    char wordInDictionary[32];
    int numberOfMeanings;
    char *wordDefinitions[10];

}Entry; //struct that describes a single entry in the dictionary

typedef struct{

    int entries;
    Entry* arrayOfEntries[100];

}Dictionary; //dictionary itself

Dictionary createDictionary(){

    Dictionary emptyDictionary;

    emptyDictionary.entries = 0;

    int i,j;

    for(i=0;i<100;i++){
        emptyDictionary.arrayOfEntries[i] = malloc(sizeof(Entry));
        emptyDictionary.arrayOfEntries[i]->numberOfMeanings = 0;
        strcpy(emptyDictionary.arrayOfEntries[i]->wordInDictionary, "");
        for(j=0;j<10;j++){
            emptyDictionary.arrayOfEntries[i]->wordDefinitions[j] = 
            malloc(500*sizeof(char));

            strcpy(emptyDictionary.arrayOfEntries[i]->wordDefinitions[j], "");
        }

    }

    return emptyDictionary; //created empty dictionary with 0 entries and empty content
}

Entry* searchWord(char word[], Dictionary *dict){

    Entry* foundWord;

    int i;

    for(i=0;i<100;i++){
        if(strcmp(dict->arrayOfEntries[i]->wordInDictionary, word) != 0){
            foundWord = NULL;
        }else{
            foundWord = dict->arrayOfEntries[i];
            break;
        }
    }

    return foundWord; //searches for a given word and returns NULL, if word is not found, or pointer to entry in the dictionary that corresponds to word, if word is found.

}

int addDefinition(char word[], char meaning[], Dictionary *dict){

    Entry* foundEntry = searchWord(word, dict);

    int returnNumber;

    if((foundEntry == NULL || strcmp(foundEntry->wordInDictionary, word) != 0) 
            && dict->entries < sizeof(dict->arrayOfEntries)/sizeof(dict->arrayOfEntries[0])){

        Entry* newEntry = malloc(sizeof(Entry)); //allocating space if searched word is not found in dictionary

        strcpy(newEntry->wordInDictionary, word); //now there is a new word in the dictionary
        newEntry->numberOfMeanings = 0; //but the new word has 0 meanings

        dict->arrayOfEntries[dict->entries++] = newEntry;

        if(newEntry->numberOfMeanings<10){ 
            newEntry->wordDefinitions[newEntry->numberOfMeanings] = malloc(500*sizeof(char));
            strcpy(newEntry->wordDefinitions[newEntry->numberOfMeanings], meaning); //new word now has a new meaning since its meanings' amount is less than 10(which is max)
        }

        int oldNumberOfMeanings = newEntry->numberOfMeanings;
        int newNumberOfMeanings = oldNumberOfMeanings + 1;

        if(newNumberOfMeanings>oldNumberOfMeanings){
            returnNumber = 2; //returns 2 if both new entry and new definition were added into the dictionary
        }

        newEntry->numberOfMeanings++;

    }else if((foundEntry != NULL || strcmp(foundEntry->wordInDictionary, word) == 0) 
            && dict->entries < sizeof(dict->arrayOfEntries)/sizeof(dict->arrayOfEntries[0])){

        if(foundEntry->numberOfMeanings<10){
            foundEntry->wordDefinitions[foundEntry->numberOfMeanings] = malloc(500*sizeof(char));
            strcpy(foundEntry->wordDefinitions[foundEntry->numberOfMeanings], meaning);
        }

        int oldNumberOfMeanings = foundEntry->numberOfMeanings;
        int newNumberOfMeanings = oldNumberOfMeanings + 1;

        if(newNumberOfMeanings == oldNumberOfMeanings){
            returnNumber = 0; //returns 0 if no new entry and no new meaning are added to already found one
        }else if(newNumberOfMeanings > oldNumberOfMeanings){
            returnNumber = 1; //returns 1 if no new entry and one new meaning are added to already found one
        }

        foundEntry->numberOfMeanings++;
    }

    return returnNumber;
}

So this vague piece of code describes my program.所以这段模糊的代码描述了我的程序。 But the problem itself occurs when I test the code in main() :但是当我在main()中测试代码时,问题本身就会出现:

int main(void){

    Entry* entryPtr;

    Dictionary dict = createDictionary();

    entryPtr = searchWord("include", &dict);

    if(entryPtr != NULL){
        printf("\nWord found: 'include'");
    }else{
        printf("\nWord 'include' is not found in the dictionary.");
    }

    int count;

    count = addDefinition("include", "(verb) def1", &dict);
    count = addDefinition("assist", "(verb) def2", &dict);
    count = addDefinition("house", "(noun) def3", &dict);
    count = addDefinition("camera", "(noun) def4", &dict);
    count = addDefinition("valid", "(adjective) def5", &dict);

    printf("\nLast count: %i", count);

    int i, j;

    for(i=0;i<100;i++){
        if(strcmp(dict.arrayOfEntries[i]->wordInDictionary, "")!=0){
            printf("\n\t%i. %s", i+1, dict.arrayOfEntries[i]->wordInDictionary);
        }
        for(j=0;j<10;j++){
            if(strcmp(dict.arrayOfEntries[i]->wordDefinitions[j], "")!=0){
                printf("\n\t\t%i.%i. %s\n", i+1, j+1, dict.arrayOfEntries[i]->wordDefinitions[j]);
            }
        }
    }

    entryPtr = searchWord ("exam", &dict);
    if (entryPtr != NULL) {
        printf("\nWord found: 'exam'");
    } else {
        printf("\nWord 'exam' is not found in the dictionary.");
    }

    entryPtr = searchWord ("include", &dict);
    if (entryPtr != NULL) {
        printf("\nWord found: 'include'");
    } else {
        printf("\nWord 'include' is not found in the dictionary.");
    }

    count = addDefinition ("house", "(adjective) def6", &dict);
    count = addDefinition ("house", "(adjective) def7", &dict);
    count = addDefinition ("house", "(adjective) def8", &dict);

    printf("\n\nThe the value returned by the last addition: is %i.", count);

}

What the output gives is: output 给出的是:

Word 'include' is not found in the dictionary.
Last count: 2
        1. include
                1.1. (verb) def1
Segmentation fault: 11

I changed the condition in nested for loops in main() as follows:我在main()的嵌套 for 循环中更改了条件,如下所示:

for(i=0;i<5;i++){
        if(strcmp(dict.arrayOfEntries[i]->wordInDictionary, "")!=0){
            printf("\n\t%i. %s", i+1, dict.arrayOfEntries[i]->wordInDictionary);
        }
        for(j=0;j<1;j++){
            if(strcmp(dict.arrayOfEntries[i]->wordDefinitions[j], "")!=0){
                printf("\n\t\t%i.%i. %s\n", i+1, j+1, dict.arrayOfEntries[i]->wordDefinitions[j]);
            }
        }
}

Then it showed the right content, though it is not what it should be like.然后它显示了正确的内容,尽管它不是应该的样子。 Instead, it should work for all the entries in the dictionary, not first 5.相反,它应该适用于字典中的所有条目,而不是前 5 个。

I've tried doing debugging many times and investigate it myself but still could not find the solution.我已经尝试过多次调试并自己进行调查,但仍然找不到解决方案。 Any hints to solve the possible problem(-s)?有什么提示可以解决可能的问题(-s)?

PS I run the program on VS Code, macOS, GCC. PS 我在 VS Code、macOS、GCC 上运行程序。

The issue is in line问题是一致的

if(strcmp(dict.arrayOfEntries[i]->wordDefinitions[j], "")!=0)

It doesn't check for valid dict.arrayOfEntries[i]->wordDefinitions[j] pointer.它不检查有效的 dict.arrayOfEntries[i]->wordDefinitions[j] 指针。 Something like this:像这样的东西:

if(dict.arrayOfEntries[i]->wordDefinitions[j] && strcmp(dict.arrayOfEntries[i]->wordDefinitions[j], "")!=0)

Beside that, I think you are using malloc badly, you are creating at runtime a whole empty dictionary in createDictionary and then creating new entries in addDefinition and adding them like this:除此之外,我认为您使用 malloc 很糟糕,您在运行时在 createDictionary 中创建了一个完整的空字典,然后在 addDefinition 中创建新条目并像这样添加它们:

dict->arrayOfEntries[dict->entries++] = newEntry;

This newEntry replaces the old pointer and it doesn't event delete it, this is a memory leak, and beside that newEntry is not fully initialized, and that's the main reason of the segmentation fault.这个 newEntry 替换了旧指针并且它没有删除它,这是一个 memory 泄漏,而且 newEntry 没有完全初始化,这是分段错误的主要原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM