繁体   English   中英

如何修复以避免 memory 泄漏?

[英]How can I fix to avoid a memory leak?

我创建了 push_back function 以在数组末尾添加一个数字。 但我认为下面的这段代码有一些泄漏的原因。 你能找到原因吗?

void ElasticArray::push_back(int item){
    
    if(_max_size == _size){
        int* tmpArray = nullptr;
        tmpArray = new int[_size * 2];
        for(int i = 0; i < _size; i++){
            tmpArray[i] = _array[i];
        }
        _array = tmpArray;
        _max_size = _size * 2;
        delete[] tmpArray;
        tmpArray = nullptr;
    }

    else if(_max_size == 0){
        _max_size = 16;
    }

    if(_max_size > _size){
        _array[_size] = item;
        _size++;
    }
    
    _array[_size] = item;
    _size++;
}

你的整个 function 编码都错了。 由于变量管理不善,它有多个问题,从而导致memory 泄漏缓冲区溢出未定义行为

如果_max_size为 0,那么大概_size也为 0(否则您的代码中的其他地方会有更多错误),并且您最终分配了 0 个元素。 _max_size永远没有机会设置为 16。但是如果由于某种原因_max_size为 0 但_size不是,则_max_size将设置为 16 但实际上不会分配_array指向的内容,从而导致后续行为未定义访问_array的内容..

即使您确实分配了一些东西,您也会在_array上调用delete[]之前将_tmpArray分配给_array ,从而导致泄漏。 然后在刚刚分配给_array的 memory 上调用delete[] ,从而在后续访问_array的内容时导致更多未定义的行为。

更糟糕的是,即使您正确地增加了数组,您也将每个item推入数组两次,因为if(_max_size > _size)在代码中的那一点上将始终为真(如果您正确执行其他所有操作),这将最终导致缓冲区溢出,破坏 memory。

话虽如此,试试这个:

void ElasticArray::push_back(int item){
    
    if ((_max_size == _size) || (_max_size == 0)){
        int new_max = (_max_size != 0) ? (_max_size * 2) : 16;
        int* tmpArray = new int[new_max];
        for(int i = 0; i < _size; ++i){
            tmpArray[i] = _array[i];
        }
        delete[] _array;
        _array = tmpArray;
        _max_size = new_max;
    }
    
    _array[_size] = item;
    _size++;
}

您正在分配 _array = tmpArray ,然后您在 tmpArrary 上调用 delete 然后再次访问 _array

        _array = tmpArray;
        _max_size = _size * 2;
        delete[] tmpArray;
        tmpArray = nullptr;

_array 存储 tempArray 指向的 memory 位置的起始地址

例如:如果开始 memory tempArray 的位置是 0x00f39f38 那么之后

_array = tmpArray;

_array 也将指向 0x00f39f38

所以当你打电话时

delete tmpArray
tmpArray = nullptr;

tempArray 开始指向 null 0x00000000 但 _array 指向的地址仍然是 0x00f39f38 所以当你这样做时

_array[_size] = item;
    _size++;

根据操作系统和编译器,您将获得未定义的行为

建议

在执行 _array=tempArray 时使用 std::vectors 或执行深度复制

暂无
暂无

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

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