错误glibc检测到free():无效的下一个大小(快)

时间:2015-11-11 07:08:56

标签: c++ arrays memory-management memory-leaks

所以我写了一个动态数组类,我遇到了问题(我相信)设置一个临时数组来保存值,然后改变当前数组的大小,它抛出了我glibc检测到free():无效的下一个大小(快)错误。我意识到这要么意味着我要在某个地方以外的地方写作,要么我试图释放我没有分配给我的记忆,但我可以&#39 ; t似乎找到问题所在..任何帮助都会非常感激,我已经查看了我的代码大约2个小时,似乎无法找到解决问题的方法除了删除完全删除语句,这不是解决方案,因为这只会导致内存泄漏。我是C ++的新手,所以我为任何愚蠢的错误/语法道歉

ArrayList.cpp

#include "ArrayList.h"
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int& ArrayList::operator[](unsigned int i){
    return foo[i];
}

int ArrayList::size(){
    return numElements;
}
void ArrayList::downArray(){
    int* bar = foo; //temp array to hold values while I decrease the size
    capacity /= 2;
    delete foo;
    foo = new int[capacity]; //don't I lose the original pointer here? So why does it throw an error when I try to delete foo, as if I haven't allocated that memory?
    for(int i = 0; i < capacity;i++){
        foo[i] = bar[i];    
    }

}

void ArrayList::upArray(){

    int* bar = foo; //temp array to hold values while I increase the size
    delete foo;
    foo = new int[capacity*2]; //same thing here
    foo = bar;
    for(int i = capacity; i < capacity*2;i++){
        foo[i] = 0;
    }
    capacity *=2;
}

void ArrayList::push_back(int m){
    if(numElements == capacity) //full, double foo
        upArray();
    foo[numElements] = m;
    numElements++;
}

void ArrayList::erase(int m){
    bool notFound = true;   
    int i = 0;
    while(notFound)
        if(foo[i] == m){
            notFound = false;    //Ha! Found you!
            for(int j = i; j+1 < capacity; j++){
                foo[j] = foo[j+1]; //moves everything to right of m one spot left
            }
        }
        else
            i++; //keep looking
}

string ArrayList::toString(){
    stringstream sobj;
    string x;
    sobj << "[";
    for(int i = 0; i < numElements; i++){
        if(i == numElements-1) //last iteration, avoids output displaying [1,2,3,4,]
            sobj << foo[i];
        else
            sobj << foo[i] << ",";
    }
    sobj << "]";
    sobj >> x;
    return x;
}

ArrayList::ArrayList(){
    capacity = 1;   
    numElements = 0;
    foo = new int[1];
    foo[0] = 0;
}

ArrayList::~ArrayList(){
    //delete foo; //is this not the proper place to call it?
    cout << "Destructor called" << endl;
}

ArrayList.h

#ifndef _ARRAYLIST_H_
#define _ARRAYLIST_H_
#include <string>
class ArrayList
{
 public:
    ArrayList();
    ~ArrayList();

    int& operator[](unsigned int i); // int& ArrayList::operator[](unsigned int i){....}

    void push_back(int m); 
    void erase(int m);
    std::string toString();
    int size();

 private: 
  void downArray();
    void upArray();

 private:
  int capacity, numElements;
    int* foo;
};

#endif

主要功能

int main(int argc,char *argv[])
{
    ArrayList arr;

    for (int i=1;i<=50;i++)
    {
        arr.push_back(i);
    }

    cout << "Should contain numbers 1..50, is ";

    cout << arr.toString() << endl;
}

2 个答案:

答案 0 :(得分:1)

此代码存在多个问题:

int* bar = foo; //temp array to hold values while I increase the size
delete foo;
foo = new int[capacity*2]; //same thing here
foo = bar;
for(int i = capacity; i < capacity*2;i++){
    foo[i] = 0;
}
capacity *=2;

以下是此代码的一些问题:

delete foo; 一旦调用delete,就会释放内存。所以你不能再使用bar因为它指向释放的内存。

foo = bar; 您刚刚分配了内存并将指针保存在foo中,此行抛弃了该内存地址并将foo设置回原来的状态。

执行upArray的一种方法是分配新内存,复制数据,然后释放旧内存。

int* bar = new int[capacity*2]; // new array to hold values
// Copy the data
for(int i = 0; i < capacity;i++){
    bar[i] = foo[i];
}
// Zero out the rest
for(int i = capacity; i < capacity*2;i++){
    bar[i] = 0;
}
delete foo;  // delete the old memory
foo = bar;   // point to the new memory.
capacity *=2;

另请注意,由于在成员变量中有自己的已分配指针,因此必须创建复制构造函数和赋值运算符(请参阅“三条规则”)。否则,任何复制ArrayList对象的代码都将复制指针,从而导致同一内存的多次删除。

答案 1 :(得分:0)

`ArrayList arr;` will call the constructor 

ArrayList::ArrayList(){
    capacity = 1;   
    numElements = 0;
    foo = new int[1];
    foo[0] = 0;
}

创建大小为1的foo。 那么

 for (int i=1;i<=50;i++)
    {
        arr.push_back(i);
    }

push_back方法只能插入一个elemnt(因为大小为1)。 解决方案:更改for循环for (int i=1;i<=1;i++),以便toString只打印一个元素。我没有编译你的源代码。这是我的基本理解。

相关问题