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

C++伪代码中是否需用new关键字?内存释放时机咨询

问题

代码片段

while(!fileEnd)
{
    rectD *rD = new rectD();
    symbol *sb = new symbol(rD);
    
    while( true )
    {
        if(closing brace)
        {
            sb->rD->isSymbol = true;
            sb->shapes[currentSymName] = *(sb->rD); // shapes is a std::map
            allSymbol[currentSymName] = sb; // allSymbol is a std::map
            break;
        }
        else
        {
            if(condition 1)
               sb->fun1();
            if(condition 2)
               sb->fun2();
        }
    }
}     

疑问

后续程序中会使用shapes和allSymbol这两个std::map。想咨询:上述代码中是否有必要使用new关键字?

已知使用new创建的对象位于堆内存,不使用new则对象位于栈内存;堆内存需手动delete释放,栈内存会在函数作用域结束时自动释放。

虽然当前函数作用域结束后不再直接使用*rD和*sb,但整个程序运行期间都会用到包含*rD和*sb的shapes与allSymbol。因此困惑是否该使用new关键字,若必须使用,应在何处delete以避免内存泄漏?


回答

是否需要用new?

必须用。原因很明确:

  • 栈对象的生命周期仅限于当前循环迭代,每次循环结束栈上的sb和rD都会被销毁。但你需要sb存活到整个程序运行期(因为allSymbol存了它的指针),如果不用new,allSymbol里的指针会变成野指针,访问时直接触发未定义行为。
  • 对于rD,虽然shapes里存的是它的副本,但循环过程中sb的fun1()、fun2()可能还会操作这个rD,如果是栈对象,迭代结束后就失效了,sb内部的指针会指向垃圾内存。

手动管理内存的释放点

如果坚持用裸指针,得在程序彻底不需要allSymbol和相关对象时手动释放:

  1. 遍历allSymbol的每个symbol*指针,执行delete操作。注意要给symbol写正确的析构函数——如果symbol拥有rD的所有权,析构函数里要delete rD,不然rD的内存会泄漏;如果rD的所有权不属于symbol,那还要单独遍历释放所有rD(但从代码逻辑看,rD是和sb绑定创建的,应该让symbol负责清理rD)。
  2. shapes里存的是rectD的副本,std::map会自动管理这些对象的内存,不需要额外处理。

更省心的方案:用智能指针

别折腾裸指针了,直接用C++11的智能指针:

  • 把allSymbol的类型改成std::map<Key, std::unique_ptr<symbol>>(独占所有权)或者std::map<Key, std::shared_ptr<symbol>>(共享所有权),根据你的实际需求选。
  • 创建对象时用std::make_unique<symbol>(rD)或者std::make_shared<symbol>(rD),智能指针会在对象没人用的时候自动调用delete,完全不用手动管释放,从根源避免内存泄漏。
  • 连rD也可以改成让symbol内部存std::unique_ptr<rectD>,彻底把内存管理交给标准库,减少出错概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 20:15:34