3

私は、メモリのブロックを割り当てるVectorクラスを実現しようとしています。さらにアイテムを含める必要がある場合は、最終的にそれを再割り当てします。
私はこれを行うためにstd::allocatorを使用しています:

#include <iostream>
#include <stdexcept>

using namespace std;

template <class T>
class Vector
{
private:
    T* data;
    allocator<T> data_all;
    int length;
    int _size;
    static const int block_size=10;
    void init()
    {
        length=0;
        _size=block_size;
        data=data_all.allocate(block_size,NULL);
    }
public:
    Vector()
    {
        init();
    }
    int size() const
    {
        return length;
    }
    void push_back(T item)
    {
        length++;
        if(length > _size)
        {
            _size+=block_size;
            data=data_all.allocate(_size,data);
        }
        data_all.construct(&data[length-1],item);
    }
    T& operator[] (int i)
    {
        if(i<0 || i>= length)
            throw out_of_range("The index is out of vector range");
        return data[i];
    }
};

int main(int argc, char** argv)
{
    Vector<int> v;
    for(int i=0; i<20; i++)
        v.push_back(i);
    for(int i=0; i<v.size(); i++)
        cout << v[i] << "\t";
    return 0;
}

問題は、以前に割り当てられたアイテムが保持されず、次のように出力されることです。

0   0   0   0   0   0   0   0   0   0   10  11  12  13  14  15  16  17  18  19  

それ以外の:

0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15  16  17  18  19  

なぜこの振る舞い?C ++には、Cのようにreallocを使用して隣接するアイテムを再割り当てする方法はありませんか?

4

1 に答える 1

3

の2番目の引数allocateは、アロケータ古いメモリに近い新しいメモリを返そうとするために使用できるヒントですがstd::allocator、すべての要素が互いに近いため、ベクトルのようなコンテナでは無視され、かなり役に立たないです。 '連続したブロックにいます。

既存のデータをコピーすることを期待しているようです。そうではありません。古いメモリブロックから新しいメモリブロックにコピーすることによって、それを行う必要があります。

また、古いメモリがリークしています。割り当てを解除する必要があります。

あなたは次のようなものが欲しいです:

void push_back(const T& item)
{
    if (length == _size)
    {
        T* new_data = data_all.allocate(_size+block_size);
        // N.B. if any of the following copies throws new_data will be leaked
        std::uninitialized_copy(data, data+length, new_data);
        std::destroy(data, data+length);
        data_all.deallocate(data, _size);
        data = new_data;
        _size+=block_size;
    }
    data_all.construct(&data[length++],item);
}
于 2012-06-15T22:01:50.553 に答える