2017-08-10 165 views
-1

樣例程序:如何釋放局部變量的動態分配內存?

#include <stdio.h> 
#include <malloc.h> 

void f(int n) { 
    char *val = (char *) malloc(12*sizeof(char)); 
    val = "feels...."; 

    printf("%s", val); 

// free val;  // if enable, compile time error: expected ';' before 'val' free val; 
} 

int main() 
{ 
     f(1); 

     return 0; 
} 

是否釋放其動態分配的內存要求?如果是,如何。

+3

寫'免費(VAL);!'而不是 –

+5

隨着告訴你的代碼,你*不能*你* *重新分配的指針指向其它地方,導致泄漏,*未定義的行爲時*您將指針傳遞給['free'](http://en.cppreference.com/w/c/memory/free)*函數*。如果你想分配的內存包含一個字符串,那麼你必須[*複製它](http://en.cppreference.com/w/cpp/string/byte/strcpy)。請記住,字符串需要一個額外的字符作爲終止符,因此12個字符的字符串需要13個空格。 –

+1

此外,''是一個過時的頭文件,您應該爲'malloc'和'free'函數包含'' 。 –

回答

1

是的,你需要釋放內存。但是當你爲一個字符串分配內存時,填充字符串的方式不是爲它分配一個字符串,因爲它會替換你分配的內存。相反,你註定要使用該功能strcpy這樣的...

char *val = malloc(12*sizeof(char)); 
strcpy(val,"feels...."); 

printf("%s", val); 
free(val); 
1

取而代之的是:

char *val = (char *) malloc(12*sizeof(char)); 
val = "feels...."; // val points now to the string literal ""feels...." 
        // discarding the value returned by malloc 
... 
free(val);   // attempt to free the string literal which will 
        // result in undefined behaviour (most likely a crash) 

你可能想這樣的:

char *val = malloc(12*sizeof(char)); // in C you don't cast the return value of malloc 
strcpy(val, "feels...."); // the string "feels...." will be copied into 
          // the allocated buffer 
... 
free(val);   // free memory returned previously by malloc 
1

編譯問題是因爲free是一個函數,你需要把它的參數放在圓括號中。

free(val); 

另一個問題是內存泄漏。

字符串中C是真的僅用於指向包含char數據存儲器(希望)的塊。字符串的末尾用一個值爲0的char表示。要記住的是,變量只是一個像任何其他指針一樣的指針。因此...

char *val = (char *) malloc(12*sizeof(char)); 

上面一行動態分配存儲器塊和一個指針分配給它val

val = "feels...."; 

上面一行的指針分配給對val一個字符串文字覆蓋先前的指針,這是在val。在任何情況下,它都沒有觸及第一行中的內存塊malloc。此外,你已經失去了任何參考,你已經對malloc ed塊,所以它已經泄漏。沒有辦法free它。

字符串文字通常在編譯時創建,它們佔用的內存將成爲程序的一部分。這意味着它們不是來自堆(malloc從中獲取內存,也就是說,當您嘗試使用字符串文字free時,就會發生不好的事情。在現代體系結構中,程序文本被防止在OS水平,從而嘗試它free部分將幾乎肯定你的程序崩潰。

只要你不想改變字符串的內容,你不需要malloc空間給它,你可以省略malloc (和相應的free),你的程序仍然可以工作

如果你想改變字符串,獲取字符串文字的可變副本的最簡單方法是使用strdup

char *val = strdup("feels...."); 

// Do stuff with the string 

free(val); // strdup strings need to be freed 

strdup是POSIX的功能,但不是C標準的功能,使您的平臺可能沒有它。不過,實現自己的功能相當簡單。

char* myStrDup(const char* thingToDup) 
{ 
    char* ret = malloc(strlen(thingToDup) + 1); // strlen returns the length without the terminating nul. Hence add 1 to it to allocate 
    strcpy(ret, thingToDup); // Copies the entire string including the terminating nul. 
    return ret; 
}