16

動的に割り当てられた配列の先頭アドレスに割り当てられたポインタは、配列のサイズの情報を持っていないというのは本当ですか? そのため、後でポインターを介して配列を処理するために、別の変数を使用してそのサイズを格納する必要があります。

しかし、動的に割り当てられた配列を解放するときは、サイズを指定せず、代わりに「ptr を解放」または「[] ptr を削除」します。配列のサイズを解放または削除するにはどうすればよいでしょうか? 同じスキームを使用して、配列のサイズを別の変数に格納しないようにすることはできますか?

ありがとう!

4

4 に答える 4

18

ええそれはそうです。

deletenew他の情報とともに、そのサイズを含む追加情報をチャンクに追加するため (通常は領域がユーザーに返される前)、メモリ チャンクのサイズを認識します。これはすべて実装固有のものであり、コードでは使用しないでください。

最後の質問に答えるには:いいえ-使用できません-プラットフォームとコンパイラに大きく依存する実装の詳細です。


たとえば、K&R2 で示されたサンプル メモリ アロケータでは、これは割り当てられた各チャンクの前に配置された「ヘッダー」です。

typedef long Align; /* for alignment to long boundary */

union header { /* block header */
  struct {
    union header *ptr; /* next block if on free list */
    unsigned size; /* size of this block */
  } s;

  Align x; /* force alignment of blocks */
};

typedef union header Header;

sizeは、割り当てられたブロックのサイズです (その後free、 またはによって使用されdeleteます)。

于 2010-01-09T18:38:07.823 に答える
7

面白いのは、歴史的にはそのままだっdelete [20] arr;たということですarr = new int[20]。しかし実際には、サイズに関する情報はアロケータによって問題なく格納できることが証明されており、それを使用しているほとんどの人がとにかく格納していたため、標準に追加されました。

もっと面白く、ほとんど知られていないのは、この「拡張された削除構文」が実際にはいくつかの C++ コンパイラでサポートされているという事実です (C++98 標準に直面しても正しくないにもかかわらず)。

int* arr = new int[20];
delete [20] arr;

ただし、これに関する悲しい部分は、渡されたサイズを自分で使用するために取得する標準準拠の方法がないことです:-/

于 2010-01-09T18:45:05.803 に答える
3

配列に配列のサイズが含まれていないことは事実です。後でその情報を保存する必要があります。配列を削除するとき、deleteまたはfreeそれは、割り当てられたメモリへのポインタです。(システムによって、または new と delete をオーバーライドする独自のカスタムによって) 使用されるメモリ マネージャーは、解放されたメモリ領域を認識し、それを追跡します。それが理にかなっていることを願っています。

于 2010-01-09T18:40:30.080 に答える
2

はい、それは本当だ。これは、これを直接処理することはめったになく、代わりに標準のコンテナーを使用するべきである理由の一部です。これに対処する意味があるのは、コンテナを自分で実装することにした場合のみです (この場合、通常、コンテナの実装でサイズ情報を追跡します)。

于 2010-01-09T18:42:18.843 に答える