2012-05-05 12 views
4

ポインタを解放するという理論的な質問があります。長さを知らずにポインタを解放する

私はいくつかの男(プログラム自体、またはOS)はポインタとその長さを記録しなければならないと思います。どうして?

float* pointer1 = malloc(100 * sizeof(float)); 

例:ここには浮動ポインタがあります。誰かが私のポインタ1配列の長さは何ですか?実行時に関数/メソッドを呼び出すと、そのポインタの長さを取得する方法はありませんか?だから、プログラム(またはOS)が実行時に、それの本当の長さを知らなくても、ポインタのメモリ部を解放することができますどのように:

free(pointer1); 

プログラムを解放するポインタの長さを知っていた場合は、なぜ私たちはその情報を入手することができず、長さを追跡するためにいくつかの他の方法を使用することができません。例:

struct floatArray 
{ 
    float* pointer; 
    int length; 
} 

この問題は本当に興味があります。私は、OSがどのようにポインタの長さを気にかけているかを知りたい。

ありがとう、

Sait。

+0

「ポインタを解放する」のようなものはありません。あなたはmallocによって得られた*オブジェクト*を解放します。そのオブジェクトへのポインタは、そのオブジェクトを解放する目的で参照する方法ですが、ポインタを解放していません。あなたはそのオブジェクトを解放しています。 –

+0

@R ..はい、そうです。私は言っておくべきである: "ポインタを使用してメモリに格納されたオブジェクトを解放する"。 +1。 – Sait

答えて

3

libraries-異なるコンパイラ/標準Cの間で変化するので、それを行うための標準的な方法は、存在しない、と指摘しました。これには、ブロックのサイズに加えて情報が含まれている可能性があります。

これを実装する一般的な方法の1つは、ユーザープログラムがブロックを参照するために使用するメモリアドレスのすぐ下のメモリにメタデータを格納することです。したがって、mallocの呼び出しでアドレスpが返され、メタデータにnバイトが含まれている場合、メタデータはp-np-1のアドレスに格納されます。

+0

なぜ、ポインタの長さを取得するグローバル関数がないのですか?何かが好きです:int GetLength(void * pointer)。それは役に立たないでしょうか? – Sait

+1

@zagyそれは役に立ちます。しかし、Cの設計者は、そのような方法で実装者を制約しないことを選択しました。多くの実装には、実装固有の拡張などの関数が含まれます。 –

2

通常は直接OSではありませんが、実装はmalloc()です。メモリマネージャーは、OSからより大きなメモリブロックを取得します。通常、この情報はリンクされたリストに格納されますが、libcのmalloc()を調べて、この情報が実際にどのように格納されているかを確認することをお勧めします。

として実装は、メモリマネージャが実際にメモリの割り当てられた各ブロックについてのメタデータを維持しない

+0

'malloc()'の実装をチェックすることをお勧めします。ありがとう。 – Sait

1

OSが要求した正確な長さを追跡するとは限りません。多くの場合、長さはさまざまな内部的な理由により変更(増加)されるか、アクセスが遅い方法で保存されます。それには、追加の情報がエンコードされている場合があります(通常、サイズは2の累乗の倍数の倍数に合わせられ、下位ビットはフラグとして使用されます)。一部のmalloc実装(特に組み込み関数)では、単にfree()を実装していないため、この情報を格納する必要はありません。

C言語の設計者は、このような自由度をCライブラリの実装に許したかったので、プログラムがmallocされたバッファのサイズを取得することを許可しませんでした。

+0

誰も使用したメモリ空間を把握していない場合、誰かに空のメモリ空間を与えることは可能でしょうか?それは私には意味がありません。私たちが使っているプラ​​ットフォームは、そのような場合にはもっと不安定でなければならないと思います。 – Sait

+0

@zagy、いいえ、起動時に空のヒープを設定し、開始点へのポインタを設定し、誰かがmallocsを追加したときに追加します。最終的にメモリが不足し、再起動する必要があります。起動時にmallocの束が存在する組み込みシステムでは、通常はこれだけが表示され、その後は再びmallocされません。 Linuxカーネルのブートデコンプレッサーもこれを行います。実際のカーネルを解凍すると、そのヒープは完全に消去されます。 – bdonlan

1

はMSVCまたはMinGWのを使用すると、(非標準を!)を使用することができ、機能_msize

float* pointer1 = malloc(100 * sizeof(float)); 
printf("%lu bytes with %lu elements", (unsigned long)_msize(pointer1),(unsigned long)_msize(pointer1)/sizeof*pointer1); 
+0

興味深い...私は本当にそのような機能が存在するかどうかはわかりませんでした。ありがとう。そして私はそれが非標準であることを聞いて悲しいです。 – Sait