简体   繁体   English

由于new()或malloc导致的内存泄漏

[英]Memory leak because of new() or malloc

I'm trying to implement an alternative to usual contiguous dynamic arrays, where I am using a vector of pointers, each is pointing to a constant size array, referring to it as XVector. 我正在尝试实现通常的连续动态数组的替代方案,其中我使用的是指针向量,每个指针都指向一个恒定大小的数组,将其称为XVector。

It works fine for a certain limit of inputs - say 150 elements -, but beyond that it starts throwing exceptions. 对于一定的输入限制(例如150个元素),它可以正常工作,但超出此限制,它将引发异常。

I tried to use "new and delete" instead of "malloc and free", it did increased the limit - say about 1200 elements -, but still exists the same problem. 我尝试使用“ new and delete”而不是“ malloc and free”,它确实增加了限制(例如大约1200个元素),但是仍然存在相同的问题。

I'm using C++. 我正在使用C ++。

Here's my main program: 这是我的主要程序:

XVector<int> xv;

for(int i=0;i<1210;i++){
    int temp = rand()%100;
    xv.pushBack(temp);
}


for(int i=0;i<xv.size();i++){
    cout<<xv.getValue(i)<<" ";
}

cout<<"\n\n"<<xv.capacity();
return 0;

And here's is the XVector (The class of theD header file: 这是XVector(D头文件的类:

private:
    const int b = 10;
    vector<T*> arr;
    int currentIndex;
    int maxSize;


protected:
    void expand(){
        T* temp = new T[b];
        arr.push_back(temp);
        maxSize+=(b);

    }

    void shrink(){
        delete[] arr[arr.size()-1];
        arr[arr.size()-1] = NULL;
        arr.pop_back();
        maxSize-=(b);
    }

    int ceil(float num) {
        int inum = (int)num;
        if (num == (float)inum) {
            return inum;
        }
        return inum + 1;
    }

    pair<int,int> position(int index){
        pair<int,int> pos;
        float result = ((float)index/b);
        pos.first = result; //Row #
        pos.second = ceil((result - pos.first)*b); //Exact cell in the row
        return pos;
    }



    public:

    XVector(){
        currentIndex=0;
        maxSize=b;
        arr.reserve(120);
        arr.push_back(new T[b]);
    }

    void pushBack(T value){
        if(currentIndex>=maxSize-1){expand();}
        pair<int,int> indeces = position(currentIndex);
        arr[indeces.first][indeces.second]=value;
        currentIndex++;
    }

    void popBack(){
        currentIndex--;
        if(maxSize>=currentIndex+(2*b)){shrink();}
    }

    T getValue(int index){
        pair<int,int> indeces = position(index);
        return arr[indeces.first][indeces.second];
    }

    void setValue(int index,T value){
        pair<int,int> indeces = position(index);
        arr[indeces.first][indeces.second] = value;
    }

    int capacity(){
        return maxSize;
    }

    int size(){
        return currentIndex;
    }

    bool empty(){
        return currentIndex==0?true:false;
    }

PS: I tried to use Valgrind, but failed to identify the exact problem. PS:我尝试使用Valgrind,但未能确定确切的问题。

Your program leaks memory because you never free the pointers in a destructor. 您的程序泄漏内存,因为您从不释放析构函数中的指针。 You must implement a destructor to solve your memory leak (in addition to a move constructor, copy constructor, assignment copy, and assignment move). 您必须实现一个析构函数来解决内存泄漏(除了move构造函数,copy构造函数,赋值副本和赋值移动)。

In addition to valgrind, you can use ASAN which has better output and also runs faster. 除了valgrind之外,您还可以使用ASAN ,它具有更好的输出并且运行速度也更快。

The main problem of your code that leads your code to crash isn't memory leak. 导致代码崩溃的代码的主要问题不是内存泄漏。 Totally memory leak doesn't leads to crash in short term. 完全内存泄漏不会在短期内导致崩溃。 in memory leak case your application works until there is enough space on your RAM and then if your RAM being full , crash occurs. 在发生内存泄漏的情况下,您的应用程序将一直运行,直到RAM上有足够的空间,然后如果RAM已满,则会发生崩溃。 you make a mistake in position() method in finding second dimension index. 您在寻找第二维索引时在position()方法中犯了一个错误。

For example when you call position(index:29) because of implementation of float and float precision result of (result - pos.first)*b is 9.00000095 . 例如,由于实现float和float精度而调用position(index:29)时, (result-pos.first)* b的结果9.00000095 It means its result has a little difference with real result(9). 这意味着它的结果与实际结果有一点差异(9)。 and then you call ceil(9.00000095) and it return 10 for result. 然后调用ceil(9.00000095) ,结果将返回10。 It means you access index 10 for your second dimension whereas you can use index from 0 to 9 and you have index out of range access that leads you to crash after some period of time and your program may have undefined behavior. 这意味着您可以为第二维访问索引10,而可以使用0到9之间的索引,并且索引超出范围访问,这会使您在一段时间后崩溃,并且程序可能具有未定义的行为。

the correct sample for position method is : 正确的位置方法样本是:

pair<int, int> position(int index){
    pair<int, int> pos;
    float result = ((float)index / b);
    pos.first = result; //Row #
    pos.second = index%b; // changed line
    return pos;
}

Finally you should define destructor and delete all memories you allocated by new operator. 最后,您应该定义析构函数并删除新操作员分配的所有内存。 All of vector element(arrays) need to be deleted. 所有向量元素(数组)都需要删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM