You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用delete[]无法正确释放Matrix类动态数组,触发断言失败

使用delete[]无法正确释放Matrix类动态数组,触发断言失败

兄弟,你的问题根源是对delete[]的一个非常常见的误解——C++里调用delete[]释放内存后,根本不会自动把原指针置为NULL!你那些断言之所以失败,完全是因为这个错误的假设。

咱们一点点拆解问题:

  • 当你执行delete[] matrixM[i];时,只是把这块内存还给了操作系统,但matrixM[i]这个指针本身的值还是原来的内存地址(现在变成了野指针,指向的内存已经无效),所以你紧接着断言matrixM[i] == NULL,肯定会触发失败,因为指针值根本没被修改。
  • 更离谱的是你delete[] matrixM;之后居然断言matrixM != NULL——这逻辑完全反了,虽然这个断言不会触发失败(因为指针还是原来的地址),但它没有任何意义,你都已经释放了matrixM的内存,这个指针已经是野指针了,检查它是不是NULL毫无价值。
  • 同理,sum_rowsM和sum_colsM的断言也是错的,delete[]后它们的指针值也不会自动变成NULL。

那该怎么修正呢?有两种思路:

思路1:去掉错误的断言(推荐)

其实delete[]执行成功的标志不是指针变成NULL,而是你确实对每一块用new[]分配的内存都调用了对应的delete[]。这些断言不仅没用,还会误导你觉得释放失败了。修正后的代码:

void Matrix::destroy()
{   
    for(int i=0; i < rowsM; i++){
        delete[] matrixM[i];
    }
    delete[] matrixM;
    
    delete[] sum_rowsM;
    delete[] sum_colsM;
}

思路2:手动置空指针后再断言(如果非要保留断言)

如果你确实想通过断言验证,那必须手动把指针赋值为NULL,因为C++不会帮你做这件事。修正后代码:

void Matrix::destroy()
{   
    for(int i=0; i < rowsM; i++){
        delete[] matrixM[i];
        matrixM[i] = NULL; // 手动置空
        assert(matrixM[i] == NULL); // 现在断言会成功
    }
    
    delete[] matrixM;
    matrixM = NULL;
    assert(matrixM == NULL);
    
    delete[] sum_rowsM;
    sum_rowsM = NULL;
    assert(sum_rowsM == NULL);
    
    delete[] sum_colsM;
    sum_colsM = NULL;
    assert(sum_colsM == NULL);
}

不过要提醒你:手动置空指针只有在之后还要用到这些指针(比如判断是否已经释放)的时候才有意义,像destroy这种清理函数,执行完之后对象大概率不会再被使用,所以手动置空其实不是必须的,去掉那些多余的断言反而更简洁。

另外补充个小知识点:C++标准里从来没有规定delete/delete[]要修改指针的值,不同编译器可能有不同实现,但几乎所有主流编译器都不会自动把指针置为NULL,所以以后别再做这种断言啦!

备注:内容来源于stack exchange,提问作者Arol Nokam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.16 02:54:35