2017-08-10 5 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)*関数*に渡します。割り当てられたメモリに文字列を含めるには、[* copy * it](http://en.cppreference.com/w/cpp/string/byte/strcpy)が必要です。文字列にはターミネータに余分な文字が必要なので、12文字の文字列には13のスペースが必要です。 –

+1

また、 ''は古いヘッダーファイルであるため、 'malloc'と' free'関数に '' 。 –

答えて

1

はい、メモリを解放する必要があります。しかし、文字列にメモリを割り当てるとき、文字列を設定する方法は、割り当てたメモリを置き換えるときに文字列を割り当てることではありません。代わりにあなたが...このように本の代わりに

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

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

を機能strcpyを使用することを意図している:

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のメモリブロックには触れていません。さらに、ブロックが漏れてしまったので、あなたは参照ブロックを失ってしまいました。 freeへの道はありません。

通常、文字列リテラルはコンパイル時に作成され、占有するメモリはプログラムの一部になります。これはヒープから来ていないことを意味します(mallocはそのメモリを取得します)。つまり、free文字列リテラルを試すと、悪いことが起こります。近代的なアーキテクチャでは、プログラムテキストはOSレベルではそれのfree一部にしようとすると、ほぼ確実にあなたのプログラムがクラッシュします。

限り、あなたは文字列の内容を変更したくないとして、あなたはそれにmalloc空間にする必要はありません。あなたはmallocを省略することができます文字列リテラルの変更可能なコピーを取得する最も簡単な方法は、文字列を変更する必要があります。 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; 
} 
関連する問題