一般的なアロケーターでの最適化されていない割り当てには、いくらかのオーバーヘッドが伴います。INFO ブロックと STORAGE ブロックの 2 つの「ブロック」を考えることができます。情報ブロックは、おそらく STORAGE ブロックのすぐ前にあります。
したがって、割り当てると、メモリに次のようなものがあります。
Memory that is actually accessible
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
--------------------------------------------
| INFO | STORAGE |
--------------------------------------------
^^^^^^^^^
Some informations on the size of the "STORAGE" chunk etc.
さらに、ブロックは特定の粒度 (int の場合は 16 バイトのようなもの) に沿って整列されます。
すぐにテストできるので、これが MSVC12 でどのように見えるかについて書きます。
私たちの記憶を見てみましょう。矢印は 16 バイト境界を示します。
単一の 4 バイト整数を割り当てると、特定の 16 バイト境界 (2 番目の境界の後のオレンジ色の四角) で 4 バイトのメモリが得られます。このブロックの前にある 16 バイト (青いブロック) は、追加情報を格納するために占有されています。(エンディアンなどはここでは省略しますが、これがこの種のレイアウトに影響を与える可能性があることに注意してください。) 割り当てられたメモリの前にあるこの 16 バイト ブロックの最初の 4 バイトを読み取ると、割り当てられたメモリの数がわかります。バイト。
ここで 2 番目の 4 バイト整数 (緑色のボックス) を割り当てると、INFO ブロック (黄色/赤色) がその前に収まる必要があるため、その位置は 16 バイト境界の少なくとも 2 倍になりますが、右隣の境界ではそうではありません。 . 赤いブロックは、バイト数を含むブロックです。
簡単にわかるように、緑のブロックが 16 バイト前にあった場合、赤とオレンジのブロックがオーバーラップします。これは不可能です。
それは自分で確認できます。私はMSVC 2012を使用していますが、これはうまくいきました:
char * mem = new char[4096];
cout << "Number of allocated bytes for mem is: " << *(unsigned int*)(mem-16) << endl;
delete [] mem;
double * dmem = new double[4096];
cout << "Number of allocated bytes for dmem is: " << *(unsigned int*)(((char*)dmem)-16) << endl;
delete [] dmem;
版画
Number of allocated bytes for mem is: 4096
Number of allocated bytes for dmem is: 32768
そして、それは完全に正しいです。したがって、MSVC12 の場合、new を使用したメモリ割り当てには、サイズが少なくとも 16 バイトの追加の「INFO」ブロックがあります。