1

演習用のベクトルを実装しています。

私は次のことをしたい:

100コンストラクターを呼び出さずに、最初に要素を割り当てます。オブジェクトがベクトルに追加されるたびに、ベクトルが大きくなりすぎてすべてのオブジェクトを含めることができなくなるまで、オブジェクトはコンストラクターを呼び出します。ベクトルがいっぱいになると、他の100オブジェクトを割り当てます。

これはコードです:

#include <iostream>
#include <memory>
#include <exception>
#include <cstdarg>

using namespace std;

class indexOutOfBounds:exception
{
    const virtual char* what()
    {
        return "Index out of bounds";
    }
};

template <class T>
class Vector
{
private:
    T* data;
    allocator<T> data_all;
    int length;
    int _size;
public:
    static const int block=100; // the size of a single allocation block
    Vector()
    {
        data=data_all.allocate(block,NULL);
        length=0;
        _size=block;
    }
    Vector(int n,...)
    {
        va_list vl;
        T temp;
        va_start(vl, n);
        for(int i=0; i<n;i++)
        {
            temp=va_arg(vl,T);
            push_back(temp);
        }
        va_end(vl);
    }
    int size() const
    {
        return length;
    }
    void push_back(T item)
    {
        length++;
        if(length==_size)
        {
            _size+=block;
            data=data_all.allocate(_size,data);
        }
        data_all.construct(&data[length-1],item);
    }
    T& operator[] (int i) throw()
    {
        if(i<0 || i>=length)
            throw indexOutOfBounds();
        return data[i];
    }
    ~Vector()
    {
        for(int i=0; i<length;i++)
        {
            data_all.destroy(&data[i]);
        }
        data_all.deallocate(data,_size);
    }
};

int main(int argc, char** argv)
{
    Vector<int> v(1,0);
    cout << v[0] << endl;
    return 0;
}

印刷しようとすると例外が発生しますv[0]

EXC_BAD_ACCESS(コード= 1、アドレス= 0x0)

たぶんそう&v[0]ですがNULL、理由がわかりません。でコンストラクターを使用せず、va_list次のようなメインを作成する場合:

int main(int argc, char** argv)
{
    Vector<int> v;
    v.push_back(1);
    cout << v[0] << endl;
    return 0;
}

例外はありません。誰かが理由を説明できますか?

4

2 に答える 2

4

最も可能性の高い理由は、変数引数を持つコンストラクターで、lengthまたはを初期化しないことです_size。これは、を呼び出すときにこれらの値が何であってもよいことを意味しますpush_back

アプリケーションをデバッガーで実行し、それらの変数を調べたとしたら、それは明らかだったでしょう。次回、ある種のクラッシュが発生した場合は、ここで質問する前に、デバッガーで実行し、最初にそれを理解することをお勧めします。

于 2012-06-15T13:00:26.917 に答える
3

Vector(int n,...)コンストラクターはメモリを割り当てません。初期化しないlength_size。次に、コンストラクターpush_back()からすぐに呼び出します。Vector(int n,...)を呼び出すと、両方にジャンク値が含まれているpush_backため、チェック if(length==_size)は意図したとおりに機能しません。

于 2012-06-15T12:59:50.840 に答える