td2sk の日記

技術メモとかゲームとか

STL 標準アロケータとnew/deleteのオーバーロード

C++で、new/deleteをオーバーロードしなければいけない環境で作業している。標準のnew/deleteやmalloc/freeが正しく動作しない環境なので、動作が保証される別のアロケートメソッドに差し替えないといけないわけだ。

ところで、STLにはAllocatorというテンプレートクラスがあり、多くのコンテナはこのアロケータによってメモリを割り付けている。このアロケータを差し替えることで、独自のアルゴリズムに基づくメモリ管理を実装することができる。

STLでは、デフォルトで標準のアロケータが指定されているため、特別なメモリ管理を必要としない場合、プログラマがアロケータの事を気にする必要はない。

そこで素朴な疑問。STLの標準アロケータは、オーバーロードしたnew/deleteを使ってくれるのか?
直感的には、new/deleteを差し替えた人にSTLの全てのアロケータの差し替えを要求するとは考えにくいので、標準できちんと規定されているはずだ。

調べた結果、new/deleteのオーバーロードは、STLの標準アロケータが正しく用いる。

仕様書を探すのにやや苦労した。JIS規格のC++仕様書は、一部ブラウザ非対応なうえ単語検索のできない糞仕様なので却下。ISOも購入が必要なのでスルー。
そうすると、見れるのは策定中のC++0x working draftぐらいだろう。
以下のサイトで確認できる。
C++ Project

20.6.9 The default allocator の項に、標準のアロケータが満たすべき性質が列挙してある。仕様には

  • allocate関数は::operator new(size_t)でメモリを確保すること
  • newがいつ呼ばれるか、どういった頻度で呼ばれるかは規定しない
  • deallocate関数は、::operator delete(void*)でメモリを解放すること
  • deleteがいつ呼ばれるかは規定しない

とある。頻度を指定しないというのは、ある呼び出しで大量にメモリを確保し、二度目からは初めに確保した領域を切り分ける、という実装を許すためだろう。

いずれにせよ、new/deleteさえオーバーロードしておけば、STLを使っても問題ないといえる。