内存分配不当
Improper de-allocation of memory?
在测试我的代码时,我经常收到有关使用删除的错误,因为我类的测试平台指出正在使用 new[] 分配的数组上调用 delete。 我在 ~IntVector 中删除了两个扩展函数,其中扩展函数扩展了容量,同时为动态分配的数组重新分配了内存。
如何正确使用删除来防止内存泄漏并解决此错误?
主文件
#include "IntVector.h"
#include <iostream>
#include <vector>
using namespace std;
IntVector::~IntVector(){
delete[] data;
}
void IntVector::expand(){
cap = cap * 2;
int *data2 = data;
data = new int[cap];
data = data2;
delete data2;
delete[] data2;
}
void IntVector::expand(unsigned amount){
cap = amount;
int *data2 = data;
data = new int[cap];
data = data2;
delete data2;
delete[] data2;
}
页眉
#ifndef INTVECTOR_H
#define INTVECTOR_H
using namespace std;
class IntVector{
private:
unsigned sz;
unsigned cap;
int *data;
private:
void expand();
void expand(unsigned amount);
};
#endif
使用
new[]
分配时,您必须使用 delete[]
.您的expand
函数使用普通delete
。它还包含一些其他错误(重新分配指针、双重删除等)。
你的复制构造函数在哪里?复制赋值运算符?您可能想阅读有关三法则的信息。
您可能遇到了这个问题,因为您不遵守三法则 - 您需要类中执行深层复制的复制构造函数和赋值运算符。
如果你做类似的事情
IntVector x(IntVector(10));
您将在x
中留下一个悬空的指针,因为当临时IntVector(10)
超出范围时,原始指针将被取消分配。
除了存在冲突的规则之外,您还尝试在expand
函数中删除变量两次:
void IntVector::expand()
{
cap = cap * 2;
int *data2 = data;
data = new int[cap];
data = data2;
delete data2; // this should not be here!
delete[] data2; // this will be a problem now!
}
您只能删除一次数据,如果您使用 new[]
创建了某些内容,则需要使用 delete[]
将其删除。
两个扩展函数应该看起来更像:
// copy-swap
void IntVector::expand()
{
IntVector tmp;
tmp.reserve(cap * 2);
tmp.resize(sz);
std::copy(data, data + sz, tmp.data);
std::swap(*this, tmp);
}
或
// raw implementation
void IntVector::expand()
{
unsigned int newCap = cap * 2;
int* newData = new int[newCap];
std::copy(data, data + sz, newData);
delete [] data;
data = newData;
cap = newCap;
}
复制交换版本将允许您重用其他函数(析构函数、复制赋值运算符),并且将更加异常安全。 在正确创建新数据元素之前,原始实现不应修改内部数据元素。 这可以防止new
中可能引发的异常使您的向量处于错误状态(例如,当cap
实际上不是您的容量时)。
相关文章:
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 给定一个指向堆分配内存的指针,智能指针实现如何为其找到合适的释放函数?
- 如果 const 不分配内存,为什么我可以获取 const 的地址?
- 在函数中分配内存时出现问题
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- constexpr new 如何分配内存?
- 在构造函数中分配内存失败是如何冒泡的
- LLVM 传递以在特定地址分配内存
- CudaMalloc 在分配内存时失败
- 为什么它在不分配内存的情况下工作正常
- 为什么在正确解除分配内存时出现内存泄漏?
- 如何通过 malloc 为队列数组分配内存?
- vector是否为std::移动的对象连续分配内存
- 删除类成员的动态分配内存的最佳方法是什么
- 唯一指针是否在堆或堆栈上分配内存?
- 如果不分配内存,我如何能够为变量创建和分配值?
- std::initializer_list 堆是否分配内存?
- 如何按顺序或在指定的地址分配内存?
- 是否可以使用 malloc 为类对象分配内存?
- 迭代器是否分配内存(如指针)?