为什么我不能为此指针数组元素分配NULL值?

时间:2017-08-10 16:06:02

标签: c arrays undefined-behavior

我还是C语言编程的新手。很抱歉,如果已经提出这样的问题,我真的不知道该搜索到底是什么。

作为一项练习,我正在编写一本字典。用户应该能够在练习的这个阶段添加,打印和删除单词。单词存储在名为' dict'的字符指针数组中。功能' removeWord'应确保要删除的单词替换为数组中的最后一个单词' dict'。因此,应将最后一个单词复制到必须删除的元素,然后删除最后一个元素(即将值分配给NULL)。当要删除的单词是数组中的最后一个单词时,dict'它也应该删除。

当数组中的任何单词“dict”时,程序停止运行。除了数组中的最后一个被删除。当删除除最后一个字之外的任何单词时,我想将值NULL分配给最后一个元素。

我希望我的问题很明确。我非常感谢您提供的任何帮助。

int numberOfWordsInDict(char **dict)
{
    int i,cnt=0;
    for(i=0;i<10;i++)
    {
        if(dict[i]!=NULL)
        {
            cnt++;
        }
    }
    return cnt;
}

void addWord(char **dict, char *word)
{
    int i=0;
    if(numberOfWordsInDict(dict)==10)
    {
        printf("Dictionary is already full!\n");
    }
    int k=numberOfWordsInDict(dict);
    dict[k]=(char*)malloc((strlen(word)+1)*sizeof(char));

    strcpy(dict[k],word);
}


void printDict(char **dict)
{
    int i=0;
    printf("Dictionary:\n");
    if(numberOfWordsInDict(dict)==0)
    {
        printf("The dictionary is empty.\n");

    }else
    {
        for(i=0;i<10;i++)
        {
        printf("- %s\n", dict[i]);
        }
    }
}

void removeWord(char **dict, char *word)
{
    int i,j=0;
    int swapped=0;
    j=numberOfWordsInDict(dict);
    for(i=0;i<j;i++)
    {
        if(strcmp(dict[i],word)==0 && swapped==0)
        {
        swapped=1;
        //strcpy(dict[i],dict[j-1]);
        dict[j-1] = NULL;
        }
    }

}

在dict [j-1]发生错误。

int main()
{
    char wordToBeAdded[36]={};
    char wordToBeRemoved[36]={};
    char *dict[10]={};
    char operation;

    while(1)
    {
        printf("Command (a/p/r/q): ");
        scanf(" %c", &operation);

        switch(operation)
        {
            case 'a':
                printf("Add a word: ");
                scanf(" %s", &wordToBeAdded);
                addWord(dict,wordToBeAdded);
                break;

            case 'p':
                printDict(dict);
                break;

            case 'r':
                printf("Remove a word: ");
                scanf(" %s", &wordToBeRemoved);
                removeWord(dict,wordToBeRemoved);
                break;

            case 'q':
                return 0;
        }
    }
}

3 个答案:

答案 0 :(得分:1)

问题是你删除了dict的最后一项。当您访问dict中的最后一项以将其与单词进行比较时,它已被设置为null。正如Weather Vane评论的那样,当你找到这个词时,你可能会破坏。这将阻止您在删除后访问最后一项。

void removeWord(char **dict, char *word)
{
    int i,j=0;
    int swapped=0;
    j=numberOfWordsInDict(dict);
    for(i=0;i<j;i++)
    {
        if(strcmp(dict[i],word)==0 && swapped==0)
        {
            swapped=1;
            //strcpy(dict[i],dict[j-1]);
            dict[j-1] = NULL;
        }
    }

}

因此,当i = j-1 if(strcmp(dict[i],word)==0 && swapped==0)时,这将尝试取消引用刚刚设置为null的指针。

答案 1 :(得分:0)

您的代码不会删除任何单词:因为您永远不会更改变量j的值,它所做的只是重复地将最后一个指针设置为NULL,这与从中移除特定项目无关。字符串列表。

除此之外,你的代码没有释放任何被移除的单词的空间。

此外,您的代码在软件工程的范围内是不好的,应该:

  • 将常量收集到同一位置,例如#define DICT_MAX_SIZE 10,而不是在任何地方写入值。
  • 当有更好的选择可以清楚地展示其功能时, NOT 使用无意义的变量名称,例如i j k,例如dict_sizei_head,{ {1}}等等。

答案 2 :(得分:-1)

当您遍历表并尝试从值为NULL的指针读取时,问题在于。

当你删除最后一个单词时,你永远不会到达那里。但是,如果在迭代表中时不删除最后一个,则取消引用它。

我不打算改变代码的逻辑(并且不检查它是否符合函数名称所承诺的) - 只需通过添加检查来清除指针的使用是否为NULL

void printDict(char **dict)
{
    int i=0;
    printf("Dictionary:\n");
    if(numberOfWordsInDict(dict)==0)
    {
        printf("The dictionary is empty.\n");

    }else
    {
        for(i=0;i<10;i++)
        {
        if(dict[i] != NULL) printf("- %s\n", dict[i]);
        }
    }
}


void removeWord(char **dict, char *word)
{
    int i,j=0;
    int swapped=0;
    j=numberOfWordsInDict(dict);
    for(i=0;i<j;i++)
    {
        if(dict[i] != NULL) 
           if(strcmp(dict[i],word)==0 && swapped==0)
           {
           swapped=1;
           //strcpy(dict[i],dict[j-1]);
           free(dict[j-1];
           dict[j-1] = NULL;
        }
    }

}