刺子 2021-07-08 21:43 采纳率: 100%
浏览 167
已采纳

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
已释放内存

两个实例的成员变量指向了同一块内存,当我要销毁这两个实例时,同一块的内存被释放了两次。
重复释放内存是个很危险的操作,那我现在该怎么解决这个问题?

我的理想办法是在析构函数那加一条“内存是否为空”的判断,但就一直找不到实现方法。。
还是说这就是C++内存管理的难点,只能通过合理的设计结构来避免?

  • 写回答

3条回答 默认 最新

  • bostonAlen 2021-07-08 23:58
    关注

    你这里为空判断无法生效,是因为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);  //两个类中的指针指向同一块内存 
        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 指向的内存进行了二次释放! 
        printf("a->n: %p, b->n: %p, x: %d\n", a->n, b->n, *x);
        return 0;
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 已采纳回答 7月9日

悬赏问题

  • ¥15 数学的三元一次方程求解
  • ¥20 iqoo11 如何下载安装工程模式
  • ¥15 本题的答案是不是有问题
  • ¥15 关于#r语言#的问题:(svydesign)为什么在一个大的数据集中抽取了一个小数据集
  • ¥15 C++使用Gunplot
  • ¥15 这个电路是如何实现路灯控制器的,原理是什么,怎么求解灯亮起后熄灭的时间如图?
  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 蓝桥杯单片机第十三届第一场,整点继电器吸合,5s后断开出现了问题