簡體   English   中英

在 malloc 后調用 free() 會導致意外行為

[英]Calling free() after malloc causes unexpected behaviour

嗨,我讀到我應該盡快調用free()來釋放內存,但是當我以這種方式調用 free 時,我的代碼停止正常工作。 有什么問題?

我想在每次迭代和發生錯誤時調用free()

int read_words(char *words[], int size, int max_str_len) {
    int i, j;
    char *ExtendedWord = NULL;
    for (i = 0; i < size && size != -1; ++i) {
        char tmp[1], ch, *word = tmp;
        for (j = 0; j < max_str_len; ++j) {
            if (scanf("%c", &ch) == EOF || ch == 'R') {
                size = -1;
                break;
            }
            if (ch == ' ')
                break;
            word[j] = ch;
            ExtendedWord = malloc((i + 2) * sizeof(char));
            if (ExtendedWord == NULL)
                return -1;
            strcpy(ExtendedWord, word);
            word = ExtendedWord;
            free(ExtendedWord);
        }
        word[j] = '\0';
        words[i] = word;
    }
    return i;
}
        strcpy(ExtendedWord,word);

strcpy()期望“C”字符串的第一個字符的地址作為第二個參數,它實際上是一個char數組,其中至少有一個元素等於'\\0'

指向的內存word不符合這樣的要求。

因此,調用了臭名昭著的未定義行為,可能會弄亂程序的內存管理,進而導致free()失敗。

您的代碼中有多個問題:

  • 你釋放新分配的塊而不是前一個。
  • 在將字符串傳遞給strcpy之前,您不能為空終止字符串
  • word應該初始化為NULL或分配到一塊已分配的內存,而不是指向不能傳遞給free()的本地數組。
  • 您應該復制末尾的新字符之前重新分配數組。

這是一個修改后的版本:

int read_words(char *words[], int size, int max_str_len) {
    int i, j;
    for (i = 0; i < size; i++) {
        char *word = malloc(1);
        if (word == NULL)
            return -1;
        for (j = 0; j < max_str_len; ++j) {
            int ch;
            char *ExtendedWord;
            if ((ch = getchar()) == EOF || ch == 'R') {
                size = -1;
                break;
            }
            if (ch == ' ' || c == '\n')
                break;
            /* reallocate array for one more character and a null terminator */
            ExtendedWord = malloc(i + 2);
            if (ExtendedWord == NULL)
                return -1;
            memcpy(ExtendedWord, word, i);
            free(word);
            word = ExtendedWord;
            word[j] = ch;
        }
        if (size == -1) {
            free(word);
            break;
        }
        word[j] = '\0';
        words[i] = word;
    }
    return i;
}

我讀到我應該盡快調用 free() 來釋放內存

這個描述有點模棱兩可。 僅當您將“只要我能做到這一點”解釋為“只要我不再需要分配的內存”的意思時,這才是合理的。

但是當我以這種方式調用 free 時,我的代碼停止正常工作。 有什么問題?

關於free的問題是你在完成之前釋放了內存。 隨后嘗試訪問該內存會產生未定義的行為。

代碼還有其他問題,在其他答案中討論過,但這就是free適合圖片的方式。

我想在每次迭代和發生錯誤時調用 free。

由於您的函數似乎打算通過words數組向其調用者提供指向已分配內存的指針,因此您不得在函數范圍內的任何地方釋放該內存,因為調用者(必須假定)打算使用它. 因此調用者必須承擔釋放它的責任。 該功能的文檔應清楚地描述該職責。

也許混淆出現在這里:

 word=ExtendedWord;

必須理解賦值復制的是指針,而不是它指向的空間。 之后, word指向與ExtendedWord相同的(動態分配的)空間,因此釋放ExtendedWord會使指針的兩個副本無效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM