よくわからない問題について説明が必要です。以下の 2 つのシナリオを使用すると、割り当てられるメモリの量はほぼ同じになると考えられます。ただし、シナリオ 2 ではbad_alloc
しばらくすると例外が発生し、狂ったようにメモリを食いつぶしているように見えます (プロセスに割り当てられたメモリ量のプロキシとして Windows のタスク マネージャを使用します)。以下は、MSVC10 を使用して Windows 32 ビットでコンパイルされます。
次の基本クラスがあるとします。
template<class T>
class Base
{
protected:
T x;
public:
Base() {}
Base(T _x) : x(_x){}
virtual bool func() = 0;
};
さて、派生クラスについては:
template<class T>
class Derived : public Base<T>
{
public:
Derived() {}
Derived(T _x) : Base(_x){}
bool func() { return true; };
};
ここで、2 つのケースを考えてみましょう。まず、Derived クラスの動的配列を割り当て、Derived オブジェクトで埋めます。つまり、次のようになります。
int main()
{
int size = SOME_LARGE_NUMBER;
Derived<int>* d = new Derived<int>[size];
for (int i = 0; i < size; i++)
{
d[i] = Derived<int>(i);
}
// delete here
}
次に、Base クラスのポインターの動的配列を割り当て、Derived クラスの実際のインスタンスを指すようにします。つまり、次のようになります。
int main()
{
int size = SOME_LARGE_NUMBER;
Base<int>** d = new Base<int>*[size];
for (int i = 0; i < size; i++)
{
d[i] = new Derived<int>(i);
}
// delete here
}
どちらのシナリオでも SOME_LARGE_NUMBER を 40,000,000 に設定しました。最初のシナリオでは、プログラムは問題なく完了します。2 番目のシナリオでは、bad_alloc 例外が発生します。これは予想される動作なのか、それともここで何かを見落としているのか疑問に思っています。もしそうなら、これを行うより良い方法は何ですか? vector<Base<int>*>
と を使用しても同じ問題が発生することに注意してくださいboost::ptr_vector<Base<int>>
。