2016-04-28 6 views
1

この場合、メモリを解放する正しい方法はどれですか。 2つの方法にはいくつかの違いがありますか? mallocとの両方の割り当てとはfreeでリリースするため関数内の空きメモリ

void allocateArray1(int size, int value) 
{ 
    int* arr = malloc(size * sizeof(int)); 
    /* ... */ 
    free(arr); 
} 

int* allocateArray2(int size, int value) 
{ 
    int* arr = malloc(size * sizeof(int)); 
    /* ... */ 
    return arr; 
} 

int main() 
{ 
    int* vector = allocateArray2(5,45); 
    free(vector); 
    allocateArray1(5,45); 

    return 0; 
} 
+0

明らかに違いがあります。 'allocateArray1()'では、あなたの 'main()'関数は決して配列について知りませんし、何もできません。 'main()'ができないようにするには、このメソッドを使います。 –

+0

'malloc'と' free' *はあなたの*関数がどのように働くか気にしないことに注意してください。彼らが気にするのは、 'malloc 'で割り当てられたメモリは' free'で解放されるということだけです。 – immibis

+0

'main'があなたが割り振ったメモリを混乱させることなく、呼び出された関数の範囲内で確保して自由に使うことができます。 –

答えて

3

彼らは、同等です。 allocateArray1メソッドはそれをすべて1つの関数で実行するので、メモリを解放するのを覚えやすくなります。しかし、時にはメイン(または他の機能)にメモリを提供する機能が必要なので、それを使うことができます。その場合は、後でallocateArray2メソッドのように削除するだけです。

1

これはオブジェクトを所有している(そのため、オブジェクトを解放する責任が誰であるか)、すなわち“所有セマンティクス”、として知られているもの時々あります。

一部の関数では、呼び出し元が返されたオブジェクトを解放する必要があります。 strdup()、または場合によってはPOSIX getline()機能もあります。このような場合、strdup()getline()の関数は、結果の処理の予定や結果が必要な時間を知ることができないため、関数の呼び出し元にオブジェクトを解放するタスクを委任します。

他のライブラリ関数は、ライブラリ自体によって既に寿命が維持されているオブジェクトを返すことがあるため、何も解放する必要はありません。

プロジェクトを開発して一貫した所有権セマンティクスを持つことは重要です。たとえば、オブジェクトを解放するタスクを委譲する関数は、alloc(またはnewまたはcreateなど)で始まる可能性があります。これらの関数の結果を解放することは、あなたの責任であることが常にわかります。一貫性がある限り、所有権セマンティクスがどのように定義されるかは本当に重要ではありません。

0

この場合、メモリを解放する正しい方法はどれですか。 2つの方法にはいくつかの違いがありますか?

どちらの方法も正しいです。

しかし、私はint* allocateArray2(int size, int value)関数を使用して、関数内でヒープからいくらかのメモリを割り当て、割り当てられたメモリ空間へのポインタを返すことを好むでしょう。 mallocが必要な主な理由は、コードスコープとは異なる有効期間を持たなければならないデータがある場合です。あなたのコードはあるルーチンでmallocを呼び出し、どこかにポインタを格納し、最終的に別のルーチンでfreeを呼び出します。

void allocateArray1(int size, int value)sizeが少ない場合、いくつかの処理を行い、返す前にメモリを解放する機能は効率的な方法ではありません。代わりに、スタック上に配列を作成し、それをさらに処理に使用することもできます。変数を格納するためにスタックを使用する利点は、メモリが管理されることです。メモリを手作業で割り当てる必要はなく、不要になったら解放する必要はありません。さらに、CPUがスタックメモリを効率的に編成するため、スタック変数の読み書きは非常に高速です。ただし、大きすぎるローカル配列変数を作成するなど、スタックに多くのメモリを割り当てようとすると、スタックオーバーフローが発生する可能性があります。

Cで非常に大きなスタック変数の例:

int foo() 
{ 
    double x[1048576]; 
} 

宣言された配列は、(各二重が8バイトであると仮定して)データの8 mebibytesを消費します。これがスタック上で利用可能なメモリよりも多い場合(スレッド作成パラメータまたはオペレーティングシステムの制限によって設定された場合)、スタックオーバーフローが発生します。

関連する問題