1

演習の一環として、配列を作成する別の方法を表すこのクラスを変更します。

template<class T>
class Array 
{
public:

Array(int size, T defaultvalue) : _size(size) 
    {
    _arr = new T[_size] ;
    _def = defaultvalue;
    }


Array(const Array& other) : _size(other._size) 
    {
    _arr = new T[other._size] ;
    // Copy elements
    for (int i=0 ; i<_size ; i++) 
        {
            _arr[i] = other._arr[i] ;
            }
    }

~Array() 
    {
        delete[] _arr ;
    }


Array& operator=(const Array& other) 
    {
    if (&other==this) return *this ;
        if (_size != other._size) 
        {
            resize(other._size) ;
            }
        for (int i=0 ; i<_size ; i++) 
        {
            _arr[i] = other._arr[i] ;
            }
        return *this ;
    }

T& operator[](int index) 
    {           
        if (index>_size)
        {
        int prevsize = _size;
        resize(index);
        for (int i = prevsize+1; i<=index; i++)
            {
            _arr[i] = _def;
            }
        }
        return _arr[index] ;
    }

const T& operator[](int index) const 
    {
        if (index>_size)
        {
        int prevsize = _size;
        resize(index);
        for (int i = prevsize+1; i<=index; i++)
            {
            _arr[i] = _def;
            }
        }
        return _arr[index] ;
    }

int size() const { return _size;}

T defval() const { return _def;}

void resize(int newSize) 
    {
        // Allocate new array
        T* newArr = new T[newSize] ;
    // Copy elements
    for (int i=0 ; i<_size ; i++) 
        {
            newArr[i] = _arr[i] ;
            }
    // Delete old array and install new one
        delete[] _arr ;
        _size = newSize ;
        _arr = newArr ;
    }


private:
int _size ;
T* _arr ;
T _def;
} ;

これでintの配列で問題なく動作しますが、

*** glibc が検出されました *** ./a.out: free(): 無効な次のサイズ (高速): 0x08912058 ***

たとえば、次のようにします。

const char* one = new char[3];
one = "abc";
Array<const char*> b(2, one);

これにより、長さ 2 の配列が作成され、インデックス > 2 の要素にアクセスするたびに、文字列 "abc" が返されます。そのような要素にアクセスすると、配列は本来あるべきものを返しますが、前述のエラーが発生します。エラーの後にバックトレースが続きます。

4

3 に答える 3

5

サイズ変更関数は、指定したサイズ (つまりindex) にサイズ変更されますが、配列を最大 (および含む) に設定しますindex。それは無効なインデックスです - あなたの配列は0からindex-1.

私はそれらの行について話している:

resize(index);
for (int i = prevsize+1; i<=index; i++)

したがって、この問題を解決するresizeには を呼び出す必要があります。index+1

また:

const char* one = new char[3];
one = "abc";

これは単にメモリをリークします (新しいバッファを割り当ててから、すぐに別のポインタに設定oneします)。"abc"

于 2013-08-09T20:53:23.263 に答える
2
const char* one = new char[3];
one = "abc";

上記の割り当てでは、取得したメモリ ロケーションへのディープ コピーは実行されません。one文字列リテラルを指しているため、メモリ リークが発生しています。

文字列リテラルを削除する責任はありません。それらには静的な保存期間があり、プログラムが終了すると、オペレーティングシステムはそのメモリを再利用します。

于 2013-08-09T20:53:11.637 に答える