質問
これは、動的に割り当てられた配列の先頭アドレスに割り当てられたポインタは、配列の大きさの情報を持っていないというのは本当か?だから我々は、後にポインタを通じて配列を処理するために、そのサイズを格納するために別の変数を使用する必要があります。
しかし、我々は、動的に割り当てられた配列を解放するとき、我々は、代わりに私たちだけで「自由なPTR」または「削除[] PTRを」サイズを指定しないでください。どのように配列のサイズを知って解放するか、削除するだろうか?私たちは別の変数に配列のサイズを保存しないように、同じスキームを使用することはできますか?
ありがとうございます。
解決
はい、これは本当です。
delete
が、他の情報と一緒に、そのサイズを含む、(領域がユーザに返さ通常前)チャンクに追加情報を追加するため、 new
は、メモリチャンクのサイズを知っています。これはすべての非常に多くの実装固有のものであり、あなたのコードで使用すべきではないことに注意してください。
だからあなたの最後の質問に答えるために:いいえ - 私たちはそれを使用することはできません - それは非常にプラットフォームとコンパイラに依存します実装の詳細です。
<時間>例えば、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
によって使われている)に割り当てられたブロックのサイズである。
他のヒント
面白いことは、歴史的に、それがdelete [20] arr;
で同じようarr = new int[20]
たということです。しかし実際には、サイズの情報が痛みを伴わずアロケータによって保存することができ、それを使用して、ほとんどの人はとにかくそれを保存するので、それが標準に追加されたことを証明しました。
もっと面白い、と少し知られているもの、この「拡張削除構文は」(でも、標準C ++ 98の顔に間違っているにもかかわらず)、いくつかのC ++コンパイラでサポートされている事実であるという事実は、ありますこれます。
int* arr = new int[20];
delete [20] arr;
この程度悲しい部分はすべてがあなた自身の使用のためにその渡されたサイズを取得する標準的な準拠の方法がありませんということ、である: - /
配列の配列のサイズを含んでいないことは事実である、あなたは後でその情報を保存する必要があります。 delete
介してアレイを削除するか、free
場合、それはあなたが合格に割り当てられたメモリへのポインタです。メモリマネージャは、(新しいオーバーライドからシステムや独自のカスタムのいずれかによって、削除)を使用解放されたメモリ領域を知っているし、それを追跡します。それは理にかなって願っています。
はい、それは本当です。これはめったに直接この問題に対処しようとしない、代わりに標準コンテナを使用すべき理由の一部です。あなたは(あなたが通常あなたのコンテナの実装でサイズ情報を追跡します。その場合には)コンテナ自分で実装することにした場合、それはそれに対処するために理にかなっているだけの時間についてです。