1

ベクトルを使用していますが、さまざまな理由から、ポインターを使用して個々の要素を参照しています。問題は、要素を追加すると、ベクトルのサイズが変更され、要素が別のより大きなメモリ アドレスに移動される可能性があることです。これにより、ポインターが無効になります。

再割り当てを避けるためにvector<T>::reserve、ベクターを使用する前に呼び出します。ただし、十分なスペースを予約していない場合があります。この例では、ベクトルが暗黙のうちにサイズ変更を試みるのではなく、例外をアサートまたはスローするようにしたいと考えています。

ベクトルまたは別のデータ構造を使用してこれを行う方法はありますか? C99 可変長配列を使用できますか? その場合、コンストラクターで正しい長さに初期化するにはどうすればよいですか? または、明示的にサイズ変更可能な独自のベクターをロールアウトする必要がありますか?

4

2 に答える 2

2

予約した多くのスペースを確認すると、「このインスタンスでは、黙ってサイズを変更しようとするのではなく、ベクトルにアサートまたは例外をスローさせたい」という問題を簡単に解決できます。と

if (v.size() == v.capacity()) throw ... 

次のような関数を書くことができます:

template <typename T>
void safe_vector_push_back(std::vector<T>& v, const T &e)
{
   if (v.size() == v.capacity()) throw ... 
   v.push_back(e);
}

もちろん、別の可能な方法は、ベクター内のコンテンツへのポインターをまったく格納しないことです。インデックスをベクトルに格納するだけです。そうすれば、ベクターは好きなだけサイズを変更でき、何も問題はありません。

データへのポインターを別のオブジェクト内に格納することは、通常はお勧めできません (この場合、vector はオブジェクトです)。

于 2013-04-11T10:07:07.890 に答える
1

継承はあなたの友達です:

template<typename T, typename A = std::allocator<T>>
class myvector : public std::vector<T, A>
{
    typedef std::vector<T,A> base_t;
public:
    myvector()
    {
    }

    myvector(size_t size) : base_t(size)
    {
    }
    void push_back(T val)
    {
        if(capacity() == size())
            throw "no more room";
        base_t::push_back(val);
    }
};
于 2013-04-11T13:50:40.990 に答える