既知の量の要素 (N) をロードしているベクトルがあります。
この処理により、ベクターに追加される新しい要素が動的に作成されます。
約 2 * N 個の追加要素が作成されると予想されるため、ベクターのサイズを 3 * N に変更します。
追加要素がそれを超える場合は、ベクトルの動的展開ではなく、プログラムの中止を希望します。
それを検出する方法はありますか、それは AIX/TRU64/Linux 間で移植可能ですか?
既知の量の要素 (N) をロードしているベクトルがあります。
この処理により、ベクターに追加される新しい要素が動的に作成されます。
約 2 * N 個の追加要素が作成されると予想されるため、ベクターのサイズを 3 * N に変更します。
追加要素がそれを超える場合は、ベクトルの動的展開ではなく、プログラムの中止を希望します。
それを検出する方法はありますか、それは AIX/TRU64/Linux 間で移植可能ですか?
なぜベクターを使うのですか?ベクトルの要点は、必要に応じて動的に拡張することです。
ベクトルにデリゲートするクラスを作成する代わりに、単純な配列にデリゲートするクラスを作成します。push_back でサイズを確認し、必要に応じて中止します。
何を検出しますか?ベクターのサイズが変更されるかどうか されているかどうか?
これを実現する唯一の現実的な方法は、カスタム アロケーターまたはベクターに要素を追加する関数のいずれかでチェック機能を提供することです。
例えば
template<class T>
void add_element(std::vector<T>& container, T const& v)
{
if (container.capacity()+1 >= 3*N)
{
// terminate/exception/whatever
}
container.push_back(v);
}
ベクターに委譲する独自のクラスを作成します。そして、自分の push_back でサイズを確認してください。
コンパイル時にサイズがわかっている場合は、おそらく std::tr1::array (またはboost::array ) を使用することをお勧めします。固定サイズを保持し、std::vector のようにアクセスをチェックします。
ただし、ここで他の人が言ったように、実行時にのみ知っている場合は、必要な条件をチェックする特定の関数を含むクラスにベクトルをカプセル化する必要があります (たとえば、アサーションを介して)。
この最後のアプローチでは、ベクトルの作成時に最大サイズを知ることができる場合は、カプセル化クラス コンストラクター (または初期化関数) でベクトルの最大サイズを予約 ( std::vector::reserve() ) することをお勧めします。 . そうすれば、ベクトル自体によるメモリ操作はなくなります (ベクトル要素のコンストラクタ/デストラクタがそのような操作を行う場合のみ)。次に、クラスのすべての関数の開始時と終了時にベクトル容量 ( std::vector::capacity() ) が変更されていないことを確認する単純なアサーションを追加すると、メモリが移動しないことを確認するのに役立ちます。
例(DATA_MAX_SIZEがどこかで定義されたデフォルトの最大サイズであると仮定):
template< typename MyType >
class MyData
{
public:
MyData( unsigned long max_size = DATA_MAX_SIZE )
: m_max_size( max_size )
{ m_data.reserve( m_max_size ); }
void add( const MyType& value ) { check_capacity(); m_data.push_back( value ); check_capacity(); }
private:
std::vector< MyType > m_data;
const unsigned long m_max_size;
void check_capacity() { if( m_data.capacity() != m_max_size ) throw Exception("Useful error message here!" ); }
};
またはそのようなもの...