2

デバッグ ヒープでは、次によって作成された配列のサイズを取得できますnew[]

int size = *((int *)((char *)ptr - 16));

配列のサイズが 28 未満の場合、正しく機能しています (しかし、理由はわかりませんか? 0_0)。

このトリックはリリース モード (デバッグ ヒープを使用しない) で機能しますか?

配列のサイズを取得するにはどうすればよいですか (100% 動作し、安定しています)?

4

4 に答える 4

11

実装の詳細に依存しています。これが、特定の実装が配列が配置されるメモリ領域のサイズを格納する方法です。ご覧のとおり、メモリ領域のサイズは、割り当てられた配列のサイズよりも大きくなる場合があります。

で割り当てられた配列のサイズを知る必要がある場合は、new[]その値を維持する必要があります。

于 2012-05-28T18:46:12.177 に答える
7

このような:

std::vector< int > array( 1024 ); // allocate 1024 element array.
int size = array.size();
int sizeInBytes = size * sizeof( int );

;)

あなたがやろうとしていることは、完全にコンパイラ/ライブラリに依存するものを利用することです...一般的に、あなたのコードは完全に移植できなくなるので、次のことに言及することさえありません。あなたのコンパイラのバージョンには、あなたがやろうとしていることを壊す別のメモリ割り当て実装が付属しているかもしれません...

于 2012-05-28T18:45:57.083 に答える
2

CRT から何かをマイニングする方法は定義されておらず、100% 機能しません。
あなたの唯一の方法は、サイズプレフィックスでより大きなオブジェクトを割り当てるなど、定義された場所にサイズを格納する演算子 new[] をオーバーライドすることです。

于 2012-05-28T18:48:26.280 に答える
1

他の人が述べたように、実装の詳細を使用して、割り当てられた配列のサイズを把握しています。によって返されたポインターの先頭から 16 バイト戻るnew[]と、配列のサイズを取得できることがわかりました。

16 バイトの余分な割り当ては過剰に思えますが、アプリケーションのリリース バージョンをコンパイルする場合、これは当てはまりません。実装では、おそらく、要求した長さの前後に余分なバイトを割り当て、マジック値で埋めて、配列の境界を超えるコードをキャッチできるようにします。この余分なスペースは、おそらくリリース バージョンでは割り当てられません。

また、配列のサイズがあるしきい値よりも小さい場合、16 バイトの数値はもはや有効ではないように思われると述べています。現在割り当てているものよりも大きなオブジェクトを割り当てると、そのサイズに到達するまでさらに遡らなければならない可能性があります。

したがって、利用可能なソリューションは次のとおりです。

  • 使用して割り当てを続行しnew[]、後で使用するためにサイズを保持します
  • を使用std::vectorしてサイズを取得しますstd::vector::size
  • 配列のサイズが事前にわかっていて、サイズを変更する必要がない場合は、 を使用しますstd::array。このオプションはヒープにメモリを割り当てないことに注意してください (もちろんnewstd::arrayそれ自体を割り当てない限り)
于 2012-05-28T19:02:31.583 に答える