簡體   English   中英

免費的malloc里面的function,怎么辦?

[英]free of malloc inside the function, how to do that?

我在 str function 中創建了 malloc,我想釋放這個 malloc 變量

#include <stdio.h>

char *str(void)
{
    // create the malloc
    char *string = malloc(2); // how to free it
    *(string + 0) = 'J';
    *(string + 1) = 'O';
    // return the malloc
    return string;
}

int main(void)
{
    // print the function
    printf("%s, str());
    return 0;
}
free(string)

會釋放它。 但是要將其print為字符串,最后必須有\0

注意:如果您計划在 function 調用結束時返回它,則不應在 function 內釋放它。 因為這可能會導致未定義的行為。

正確的做事方式:

char *str(void)
{
    // create the malloc
    char *string = malloc(3); // how to free it
    if(string){
       *(string + 0) = 'J';
       *(string + 1) = 'O';
       *(string + 2) = '\0';
    // return the malloc
    }
    return string;
}

int main(void)
{
    // print the function
    char *s = str();
    if(s)
       printf("%s", s);
    free(s);
    return 0;
}

不正確

如果你這樣做,那么這將是一個 memory 泄漏:

int main(void)
{
    // print the function
    printf("%s", str());
    return 0;
}

如果您這樣做,那么當您嘗試將其打印出來時就會出現未定義的行為。

char *str(void)
{
    // create the malloc
    char *string = malloc(2); // how to free it
    *(string + 0) = 'J';
    *(string + 1) = 'O';
    // return the malloc
    free(string);
    return string;
}

int main(void)
{
    // print the function
    printf("%s", str()); // undefined behavior. A dragon might appear.
    return 0;
}

通常讓調用者提供要打印的緩沖區是更好的選擇; 如果打印確實成功,可以通過返回值提示; 新的 function 簽名可能如下所示:

#include <stdbool.h>

bool str(size_t length, char buffer[length])
{
    if(length < 3)
    {
        // buffer is too short...
        return false;
    }

    buffer[0] = 'J';
    buffer[1] = 'O';
    buffer[2] = 0; // terminating null character, which you ommitted!
}

注意數組參數中的長度說明符被忽略(僅限函數參數! ),定義等同於char buffer[]char* buffer 仍然指定長度可以用來告訴用戶實際需要什么樣的參數(-> 自文檔代碼); 還要注意,這僅適用於最外層的維度(在char[12][10]中, 12被忽略,但 10 不被忽略,參數類型等同於char(*)[10] ,它是指向長度為 10) 的數組。

然后用戶可以自由地在堆上或堆棧上動態分配字符串:

int main(void)
{
    char stack[3];
    if(str(sizeof(stack), stack))
    {
        printf("%s", stack);
    }

    size_t len = 3;
    char* heap = malloc(len);
    if(!heap) // should always be checked!
    {
        // allocation failed!
        return -1; 
    }
    if(str(len, heap))
    {
        printf("%s", heap);
    }

    free(heap);

    return 0;
}

如果您仍然想保留原始簽名,那么您需要兩次返回字符串,一次打印它,一次釋放它——也就是說,您需要將它存儲在一個中間變量中才能這樣做:

int main(void)
{
    char* s = str(); // store it in a variable!
    printf("%s", s); // still need to append the null terminator for!!!
    free(s); // now you can free it

    return 0;
}

如果您沒有 append null 終止符,那么您需要明確限制要打印到控制台的字符數:

printf("%.2s", s);
//       ^^  (!)

暫無
暫無

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

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