c - 删除数组中的元素并向左移动元素以缩小间隙

标签 c arrays string memory-management

这是我的代码。该函数应该删除字符串数组中的一个字符串,然后向左移动所有元素以缩小间隙。

void removeWord(char ***array, int *count){

    char word[41];

    printf("Enter a word: ");
    fscanf(stdin, " ");
    fscanf(stdin, "%s", word);
    bool wordFound = false;
    int indexOfWord = 0;
    for(int i = 0; i < *count; i++){
            if(strcasecmp(word, (*array)[i]) == 0){
                    wordFound = true;
                    indexOfWord = i;
                    break;
            }
    }
    if(wordFound == false){
            fprintf(stderr, "Word not found in dictionary.\n");
    }
    else{
            free((*array)[indexOfWord]);
            // Decrement count
            (*count)--;
            for(int i = indexOfWord; i < *count; i ++){
                    // Shift elements over to the left by 1 to close the gap
                    (*array)[i] = (*array)[i+1];
            }
            // If the word to remove isn't the last element, remove the last element to prevent duplicate words
            if(indexOfWord != *count) free((*array)[*count]);

    }
}

当我删除数组中的最后一个单词时,该函数可以正常工作...但是当我删除倒数第二个单词时,它会删除它,但也会将最后一个元素设置为某个奇数/空值。我已经尝试解决这个问题有一段时间了,如果有人能指出我正确的方向,我将不胜感激......谢谢,如果需要更多信息,请随时询问。

------------------------更新

答案是删除最后的if语句,没有必要:

void removeWord(char ***array, int *count){

    char word[41];

    printf("Enter a word: ");
    fscanf(stdin, " ");
    fscanf(stdin, "%s", word);
    bool wordFound = false;
    int indexOfWord = 0;
    for(int i = 0; i < *count; i++){
            if(strcasecmp(word, (*array)[i]) == 0){
                    wordFound = true;
                    indexOfWord = i;
                    break;
            }
    }
    if(wordFound == false){
            fprintf(stderr, "Word not found in dictionary.\n");
    }
    else{
            free((*array)[indexOfWord]);
            // Decrement count
            (*count)--;
            for(int i = indexOfWord; i < *count; i ++){
                    // Shift elements over to the left by 1 to close the gap
                    (*array)[i] = (*array)[i+1];
            }
    }
}

最佳答案

else 的开头处,free() 删除您想要删除的单词。然后你将所有剩余的单词移过来。最终结果是您的 array[count-1](最后一个有效元素)和 array[count] 都包含相同的指针。然后释放array[count],使array[count-1]包含指向已释放内存的指针。

为什么要使用第二个free()?您想删除 1 个单词,free() 该单词即可。

另外,为什么是 char *** 数组?无论您在哪里使用它,您都会对它进行一次 (*array) 取消引用。为什么不将 char ** 指针数组传递到函数中?

关于c - 删除数组中的元素并向左移动元素以缩小间隙,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19455428/

相关文章:

计算给定边界框以及图像的宽度和高度的比例

C 结构和 malloc 函数

无法使用互斥复选框实现 TreeView

arrays - 使用线数组作为输入的语法

具有数组返回类型的 PHP 函数

Java string/stringbuilder 在MySql数据库中插入null

c - 如何在没有警告的情况下传递用户定义的固定长度数组类型(C 和 OpenCL)

C++ 关系运算符 == 与字符串

string - 调用 C# 代码时,PowerShell $null 不再为 null

C# 问题 : Why cannot I assign a string directly to a class inheriting System. IFormattable 或 System.FormattableString 而它们本身可以吗?