【问题标题】:Error free(): invalid next size (fast): 0x08912058无错误():下一个大小无效(快速):0x08912058
【发布时间】:2013-08-09 20:38:59
【问题描述】:

作为练习的一部分,我正在修改这个代表创建数组的不同方式的类:

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 *** ./a.out: free(): invalid next size (fast): 0x08912058 ***

当我这样做时,例如:

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

这应该创建一个长度为 2 的数组,并且每当我访问索引 > 2 的任何元素时,它都应该返回字符串“abc”。当我访问这样的元素时,数组会返回它应该返回的内容,但是我得到了上述错误。错误后跟回溯。

【问题讨论】:

  • 对不起。我编辑了更多错误。
  • 使用复制交换。这安全多了。您还为one 分配内存,然后立即泄漏。
  • “我愿意,例如..”:您忽略了返回的新 char 数组并将其替换为指向常量字符串“abc”的指针。您确定不想改用strcpy 吗? (这需要在你的新行中增加一个字节。)
  • 你确定不是Array&lt; char &gt;?因为您正在创建指向char 的指针数组,而不是char 的数组。另外,从您分配给char * 的方式来看,我认为您需要更好地了解那里发生的事情。
  • 是的,我想要一个指向字符的指针数组。我正在尝试学习 C++,但指针一直让我感到困惑。

标签: c++


【解决方案1】:

您的 resize 函数会调整为您给它的大小(即index),但随后您将数组设置为(包括)index。这是一个无效的索引 - 您的数组从 0 变为 index-1

我说的是那些台词:

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

所以你需要用index+1 打电话给resize 来解决这个问题。

还有:

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

这只会泄漏内存(您分配一个新缓冲区,然后立即将one 设置为"abc",这是一个不同的指针)。

【讨论】:

    【解决方案2】:
    const char* one = new char[3];
    one = "abc";
    

    上述分配不会对您获得的内存位置进行深度复制。 one 指向导致内存泄漏的字符串字面量。

    您不负责删除字符串文字。它们具有静态存储持续时间,一旦程序退出,操作系统就会回收它的内存。

    【讨论】:

    • 我明白我在第一种情况下做错了什么,但在第二种情况下没有。为什么会出现同样的问题?
    • @RobVerheyen 对不起。我没有注意到您正在分配给_def
    【解决方案3】:

    首先,不要这样做:

    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++要容易得多

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-23
      • 1970-01-01
      • 2012-10-25
      • 2012-05-22
      • 1970-01-01
      • 2017-03-28
      • 2018-05-20
      相关资源
      最近更新 更多