C++ 如何解决此内存泄漏
我试图重新创建vector类,我相信我的代码中存在内存泄漏,但我不知道如何解决它。在我的VisualStudio中使用CRT库,它告诉我每次调用reserve时都会出现一个假定的内存泄漏 我不太清楚这是为什么,或者是否有内存泄漏。内存泄漏检测表明这是reserve函数中的这一行int*temp=new int[n]强> 据我所知,这是在储备功能中发生的情况: 一旦arr的内容被复制到temp中,就可以删除arr了。分配arr=temp应该可以工作,因为我所做的就是将arr指向temp所在的位置。因为arr以前被删除了,所以堆中只有1个数组,而且arr和temp都指向同一个数组,所以应该没有内存泄漏。Temp不重要,因为它在退出作用域后消失。在后续调用reserve函数时,每件事情都会重复,并且堆中应该只有一个arr指向的数组 我相信我的想法在某种程度上可能是错误的C++ 如何解决此内存泄漏,c++,memory-leaks,C++,Memory Leaks,我试图重新创建vector类,我相信我的代码中存在内存泄漏,但我不知道如何解决它。在我的VisualStudio中使用CRT库,它告诉我每次调用reserve时都会出现一个假定的内存泄漏 我不太清楚这是为什么,或者是否有内存泄漏。内存泄漏检测表明这是reserve函数中的这一行int*temp=new int[n] 据我所知,这是在储备功能中发生的情况: 一旦arr的内容被复制到temp中,就可以删除arr了。分配arr=temp应该可以工作,因为我所做的就是将arr指向temp所在的位置。因为
#include "Vector.h"
namespace Vector {
vector::vector() {
sz = 0;
space = 0;
arr = nullptr;
}
vector::vector(int n) {
sz = n;
space = n;
arr = new int[n];
for(int i = 0; i < n; i++) {
arr[i] = 0;
}
}
void vector::push_back(int x) {
if(sz == 0) {
reserve(1);
} else if (sz == space) {
reserve(2*space);
}
arr[sz] = x;
sz++;
}
void vector::reserve(int n) {
if (n == 1) {
arr = new int[1]; //arr was a nullptr beforehand
}
int* temp = new int[n];
for(int i = 0; i < n; i++) {
temp[i] = arr[i];
}
delete[] arr;
arr = temp;
space = n;
}
#包括“Vector.h”
名称空间向量{
向量::向量(){
sz=0;
空间=0;
arr=nullptr;
}
向量::向量(int n){
sz=n;
空间=n;
arr=新整数[n];
对于(int i=0;i
我也有同样的问题。我在堆中创建了两个指向同一地址的指针。当我试图释放内存时,结果只有一个指针可以释放内存,它是指向该地址的第一个指针。指向该地址的第二个或第三个指针没有释放内存的权限奥利,但只有第一批拥有这种权力的人
范例
int *a = new int[5];
int *b = a;
int *c = a;
指针b和c也没有权限释放指针a指向的内存地址。因此,如果我说的是delete[]b
或delete[]c
,则内存没有释放权限。然后我尝试编写delete[]一个
成功了。我没有真正的答案,我只是试图通过我所做的尝试和错误来接近。这就是我得到的
<>实际上这个案例违反了规则,但是C++仍然允许我们这样做,它被称为未定义行为。我们违反了
你的代码假设在<代码> vector::该
arr
为null
void vector::reserve(int n) {
if (arr) { //handle case when arr is null
space += n;
arr = new int[space];
//no need to copy anything!
} else { //handle case when arr is not null
int* tmp(new int[space + n]);
for(int i = 0; i < space; i++) {
tmp[i] = arr[i];
}
delete[] arr;
arr = tmp;
space += n;
}
}
相反,可能会根据arr
是否为null
来划分reserve
的功能
void vector::reserve(int n) {
if (arr) { //handle case when arr is null
space += n;
arr = new int[space];
//no need to copy anything!
} else { //handle case when arr is not null
int* tmp(new int[space + n]);
for(int i = 0; i < space; i++) {
tmp[i] = arr[i];
}
delete[] arr;
arr = tmp;
space += n;
}
}
void vector::reserve(int n){
if(arr){//处理arr为null时的情况
空间+=n;
arr=新整数[空间];
//不需要复制任何东西!
}else{//处理arr不为null时的大小写
int*tmp(新int[space+n]);
for(int i=0;i
此外,上面的代码假定您的意思是保留
空格+n
,而不是允许保留
收缩数组,因为如果保留的数据少于以前的保留,则会丢失数据。通常更好的做法是在使用指针时不使用关于指针状态的假设,因为当代码变得更复杂时,假设离子最终可能会被遗忘或变得更加模糊。这里没有太多错误
漏洞
注释无法保证。没有什么可以阻止多次调用resize,包括调用reserve(1)
,这将泄漏arr
指向的任何内存。请考虑
if (arr == nullptr) {
arr = new int[n]; //arr was a nullptr beforehand
}
现在这个评论肯定是真的
每次阵列大小增加时,复制循环都会超出arr
的末端
for(int i = 0; i < n; i++) {
temp[i] = arr[i];
}
检查n
和sz
,以防止两端溢出和复制尚未设置的数据。如果没有要复制的内容,则全部完成
机会目标
该类需要一个析构函数来释放它所拥有的任何内存(),如果没有它,就会发生泄漏
vector::~vector() {
delete[] arr;
}
如果它有析构函数,则要求它具有特殊的支持函数来处理(至少)类的复制,或者明确禁止复制
// exchanges one vector for the other. Generally useful, but also makes moves
// and assignments easy
void vector::swap(vector& a, vector& b)
{
std::swap(a.sz, b.sz);
std::swap(a.space, b.space);
std::swap(a.arr, b.arr);
}
// Copy constructor
vector::vector(const vector& src):
sz(src.sz),
space (src.space),
arr(new int[space])
{
for(int i = 0; i < sz; i++) {
arr[i] = src.arr[i];
}
}
// move constructor
vector::vector(vector&& src): vector()
{
swap(*this, src);
}
// assignment operator
vector::vector& vector::operator=(vector src)
{
swap(*this, src);
return *this;
}
//用一个向量交换另一个向量。通常很有用,但也可以移动
//作业也很简单
无效向量::交换(向量a、向量b)
{
标准:掉期(a.sz,b.sz);
交换(a空间,b空间);
标准::交换(a.arr,b.arr);
}
//复制构造函数
向量::向量(常量向量和src):
深圳(src.sz),
空间(src.space),
arr(新整数[空间])
{
对于(int i=0;i
复制构造函数使用。这是有趣的:
位
赋值运算符使用。这不是实现赋值运算符的最快方法,但可能是最简单的方法。从“易”开始,如果容易,则只转到“难”
// exchanges one vector for the other. Generally useful, but also makes moves
// and assignments easy
void vector::swap(vector& a, vector& b)
{
std::swap(a.sz, b.sz);
std::swap(a.space, b.space);
std::swap(a.arr, b.arr);
}
// Copy constructor
vector::vector(const vector& src):
sz(src.sz),
space (src.space),
arr(new int[space])
{
for(int i = 0; i < sz; i++) {
arr[i] = src.arr[i];
}
}
// move constructor
vector::vector(vector&& src): vector()
{
swap(*this, src);
}
// assignment operator
vector::vector& vector::operator=(vector src)
{
swap(*this, src);
return *this;
}