《精选问答》挑选CSDN问答频道每周最新最热的优质回答,为大家提供可信赖的优质解答,点击查看更多已解决问题
目录
2、封装为类的tkinter,怎么在类外把信息写到Tkinter的text控件中
5、python 连接多个sql sql并执行sql 怎样用for或其它循环操作
1、C++内存管理 怎么避免内存重复释放?
问题描述:
两个实例的成员变量指向了同一块内存,当我要销毁这两个实例时,同一块的内存被释放了两次。
重复释放内存是个很危险的操作,那我现在该怎么解决这个问题?
我的理想办法是在析构函数那加一条“内存是否为空”的判断,但就一直找不到实现方法。。
还是说这就是C++内存管理的难点,只能通过合理的设计结构来避免?
#include <cstdio>
class Example{
public:
int *n;
Example(int *n):n(n){}
~Example(){
delete n; // if(n != NULL)并不管用, 有啥其他检查方法吗?
n = NULL;
printf("已释放内存\n");
}
};
int main(){
int *x = new int(666);
Example *a = new Example(x); //...
Example *b = new Example(x); //两个类中的指针指向同一块内存
printf("a->n: %p, b->n: %p, x: %d\n", a->n, b->n, *x);
delete a;
printf("a->n: %p, b->n: %p, x: %d\n", a->n, b->n, *x);
delete b; //对 x 指向的内存进行了二次释放!
return 0;
}
运行结果:↓
a->n: 00B12E20, b->n: 00B12E20, x: 666
已释放内存
a->n: 00B12E20, b->n: 00B12E20, x: 11611744
已释放内存
解决方案——来自@bostonAlen的回答
你这里为空判断无法生效,是因为delete后,n变成0xDDDDDDDD , 自然NULL无法判断
#include <cstdio>
class Example{
public:
int *n;
Example(int *n):n(n){}
~Example(){
if(n != (int *)0xDDDDDDDD)
{
delete n; // if(n != NULL)并不管用, 有啥其他检查方法吗?
n = NULL;
printf("已释放内存\n");
}
}
};
int main(){
int *x = new int(666);
Example *a = new Example(x); //...
Example *b = new Example(x); //两个类中的指针指向同一块内存
printf("a->n: %p, b->n: %p, x: %d\n", a->n, b->n, *x);
delete a;
printf("a->n: %p, b->n: %p, x: %d\n", a->n, b->n, *x);
delete b; //对 x 指向的内存进行了二次释放!
return 0;
}
但是这样还是有问题,第二次析构,又无法判断了,还是会对损坏。
最好的还是,不进行地址的指向,仅仅是数据的赋值。
#include <cstdio>
class Example{
public:
int *n;
Example(int *n):n(new int()){*n = *n;}
~Example(){
if(n != (int *)0xDDDDDDDD || n!=NULL)
{
delete n; // if(n != NULL)并不管用, 有啥其他检查方法吗?
n = NULL;
printf("已释放内存\n");
}
}
};
int main(){
int *x = new int(666);
Example *a = new Example(x); //...
Example *b = new Example(x); //两个类中的指针指向同