最初に
本記事の内容は、実際の開発で使わないでください。使ったとしても自己責任でお願いします。
実験用のコードであり、各コンパイラで仕様が保証されていない可能性があります。
※Visual C++とGCCでは動作しました。
配列の要素数を取得するための条件
クラスにデストラクタが実装されていることが条件です。
delete[]で配列の削除を行う際に、クラスのデストラクタを呼び出すのに要素数が必要になるからです。
逆に言えばデストラクタが無ければ、メモリ解放だけでいいので要素数が付与されません。
実装してみたコード
さっそくですが、コードの紹介です。
配列の要素数を取得するコード
#include <iostream>
class A
{
public:
virtual ~A() {} // デストラクタがあることが条件です。virtualでなくとも構いません。
};
int main()
{
// デストラクタのあるオブジェクトの配列作成
A* a = new A[10];
// 32Bit(x86)の場合は、配列の先頭アドレスの4バイト手前に要素数が入っています。
std::cout << *((uint32_t*)a - 1) << std::endl;
// 64Bit(x64)の場合は、配列の先頭アドレスの8バイト手前に要素数が入っています。
//std::cout << *((uint64_t*)a - 1) << std::endl;
delete[] a;
return 0;
}
出力
10
配列の先頭アドレスの4もしくは8バイト手前に要素数が入っていることが分かります。
これでdelete[]を行った時に全てのデストラクタを呼ぶ仕組みが実現できるわけですね。