You need to enable JavaScript to run this app. C++中使用new分配指针后执行delete触发断点,如何正确删除指针?
优惠活动
大模型
产品
解决方案
定价
更多

C++中使用new分配指针后执行delete触发断点,如何正确删除指针?

报错根因

触发程序断点的直接原因是调试版C运行时(CRT)检测到堆内存重复释放,也就是你对同一块通过new申请的堆内存执行了两次释放操作,CRT的内存校验逻辑会直接中断程序触发断点。
你代码中连续出现3个典型的指针操作错误,共同导致了这个问题:

  • 构造函数中的指针覆盖造成内存泄漏
    构造函数内的代码逻辑:
    a = new double;
    a = x;
    
    第一行通过new申请了一块double大小的堆内存,把地址存入指针a;第二行直接将a的值覆盖为外部传入的x的地址,最开始new出来的那块内存从此没有任何有效指针指向,永远无法被释放,形成永久内存泄漏。b、c指针的处理逻辑和a完全一致,存在同样的问题。
  • delete语句中的逗号表达式语义陷阱
    你写的所有类似delete a, b, c;的代码,本质是C++的逗号操作符:整个表达式会从左到右依次执行每个子表达式,但只有最后一个子表达式的结果会作为整个语句的返回值。
    这类语句的实际执行逻辑是:
    1. 对a指向的内存执行delete
    2. 取出b的值(不执行任何内存操作)
    3. 取出c的值(不执行任何内存操作)
      整个语句根本不会对b、c指向的内存执行释放操作。
  • 跨作用域的内存重复释放
    main函数中通过new申请了j、k、l三块堆内存,将其地址传入类对象后,类的析构函数会对a(即j的地址)执行一次delete;但main函数末尾又对j的地址执行了一次delete——同一块堆内存被连续释放两次,直接触发CRT的断点校验。
修复方案
  • 明确内存所有权:动态申请的堆内存必须由唯一的主体负责释放,禁止跨作用域对同一块内存执行delete操作。
  • 修正构造函数逻辑:如果类需要自主管理内存,就需要在new申请空间后,把外部传入的值拷贝到申请的内存中,不能直接覆盖指针指向的外部地址:
    userValue::userValue(double *x, double *y, double *z)
    {
        discrim = 0;
        a = new double(*x); // 申请内存后拷贝对应值,不直接存外部指针地址
        b = new double(*y);
        c = new double(*z);
    }
    
  • 修正所有delete语句的写法:每个指针的释放操作单独编写,禁止用逗号拼接多个delete目标:
    userValue::~userValue()
    {
        delete a;
        delete b;
        delete c;
    }
    
  • 如果选择由main函数负责管理所有内存,那么类的析构函数绝对不能执行delete操作,仅保留指针指向的地址用于运算,所有内存释放逻辑全部放在main函数中,同样需要逐个执行delete操作。
  • 场景优化:对于这个二次方程求解的场景,完全不需要使用指针,类成员直接存储double类型的数值即可,从根源上规避动态内存操作的各类风险。

内容的提问来源于stack exchange,提问作者Joel Gray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.26 15:06:05