作为练习的一部分,我正在修改这个代表创建数组的不同方法的类:
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;
} ;
现在这适用于整数数组,但它给了我
*** glibc detected *** ./a.out: free(): invalid next size (fast): 0x08912058 ***
当我这样做时,例如:
const char* one = new char[3];
one = "abc";
Array<const char*> b(2, one);
这应该创建一个长度为2的数组,并且每当我访问索引为&gt;的任何元素时2,它应该返回字符串“abc”。当我访问这样的元素时,数组返回它应该的内容,但是我得到了上述错误。错误之后是回溯。
答案 0 :(得分:4)
您的调整大小功能会调整为您提供的大小(即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"
,这是一个不同的指针。)
答案 1 :(得分:2)
const char* one = new char[3];
one = "abc";
以上分配不会对您获取的内存位置进行深层复制。 one
指向导致内存泄漏的字符串文字。
您不负责删除字符串文字。它们具有静态存储持续时间,并且一旦程序退出,操作系统就会回收它的内存。
答案 2 :(得分:1)
首先,不要这样做:
const char* one = new char[3];
one = "abc";
如果你想要这样的话,你需要使用new
:
char* one = new char[4];
one[0] = 'a';
one[1] = 'b';
one[2] = 'c';
one[3] = 0; // null terminator
但是,当你只想要它指向string literal(如“abc”)时,那就太过分了。就这样做:
const char* one = "abc";
此外,如果您使用std::string
而不是char*
,您会发现C ++更容易 。