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

时间:2013-10-18 17:16:17

标签: 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]);

    }
}

当我删除数组中的最后一个单词时,该函数正常工作...但是当我删除第二个到最后一个单词时,它会删除它,但也会将最后一个元素设置为某个奇数值/ null。如果有人能指出我正确的方向,我一直试图绕过这一段时间,我会非常感激...谢谢,如果需要更多的信息,请不要犹豫。

----------------------- UPDATE

答案是最后删除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];
            }
    }
}

2 个答案:

答案 0 :(得分:0)

问题在于此代码:

if(indexOfWord != *count) free((*array)[*count]);

问题是由于你已经递减了*count,所以现在如果你使用修改后的*count引用它,它将引用当前实际的最后一个值。 也不需要释放最后一个元素,因为当前最后一个元素和前一个最后一个元素指向同一个内存所以,只需将指针设置为NULL

将其更改为:

if(indexOfWord != *count) (*array)[((*count) + 1)] = NULL;

答案 1 :(得分:0)

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

为什么第二个free()呢?你想删除1个单词,你free()那个单词,你已经完成了。

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