[英]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.