newした配列は最後にdelete[]を使って解放するわけですが、「何個解放するか」は誰が知ってるのか。
コンパイラによって異なると思いますが、GCC 4.6では先頭要素の1つ前にサイズが入ってました。
#include <iostream> struct X { X() { std::cout << "ctor" << std::endl; } ~X() { std::cout << "dtor" << std::endl; } }; int main() { const std::size_t n = 3; X* xs = new X[n]; std::cout << *(reinterpret_cast<std::size_t*>(xs) - 1) << std::endl; delete[] xs; }
ctor ctor ctor 3 dtor dtor dtor
ただし、デストラクタを呼ぶ必要のない型については、サイズがどこにもなかったりします。
#include <iostream> int main() { const std::size_t n = 3; int* xs = new int[n]; std::cout << *(reinterpret_cast<std::size_t*>(xs) - 1) << std::endl; delete[] xs; }
1442542072972412669
こういうのをうまく使えば、サイズ変数を内部に必要としない可変長配列クラスを作れたりすると思います。
と、こういう話を大阪に行った時に id:melpon から聞いたので試してみました。