谁负责删除?

时间:2012-06-20 12:39:26

标签: c++ dynamic delete-operator

我正在分析代码,我对特定代码感到困惑。 我发布了代码/伪代码,它们将传达相同的含义。

第1课

Class1::Func1()
{
    Collection* cltn;   
    try
    {
        cltn = Class2::get_records_from_db();
    }
    catch(Informix error)
    {}
    catch(DB Error)
    {}
    catch(...)
    { Unknown exception }          //I get this error always once the process processes lot of records   
}

第2课

Collection* Class2::get_records_from_db()
{
    Collection *clt = new Collection();
    try
    {

        //Query database
        For each row in query result
        Row *row = new row();
        populate(row)
        clt->add(*row)

         ...
        if( Informix error)
        {
            throw Informix error;
        }  
     }

     catch(...)
     {
          delete clt;  //Who will delete row?
          clt = 0;
          throw Db error 
     }

    return clt;  //Who will delete clt?
}

问题 - 第2部分

感谢您对第一个问题的见解。现在这是正在发生的真正问题。

Class 1是一个C ++进程,Class 2是一个与Informix数据库对话的库。 Class2::get_records_from_db()是一个查询Informix DB并返回结果集的函数。我已经增强了上面的代码,它更类似于真正的代码。

Collection个对象会处理200k个row个对象,正如大多数人所说的那样,这些对象无法正常释放。
调用者在常规catch块中看到“Unknown exception”。可能是因为Class 2中创建的巨大内存泄漏?

我还在日志中看到一些Informix错误406 (Out of memory error)。在吐出一系列Unknown Exception& SQLERR406

我想知道核心转储是否是内存泄漏的副产品。

2 个答案:

答案 0 :(得分:12)

  

您提供的代码有什么问题?

您提供的代码示例是一个非常错误和错误的代码。

没有人删除( rowclt )。这会导致 内存泄漏 未定义行为 ,具体取决于其析构函数是否具有琐碎或非平凡的实现。这意味着可能会发生非常糟糕的事情。

如果使用new分配对象,则需要通过在delete返回的指针上调用new来显式释放它。由于您没有在任何一个指针上调用delete,因此它们都不会被释放。

  

谁应该负责删除?

物品本身!
对象应具有内置功能,以便在其范围({})结束后立即取消分配。这样,没有人需要显式释放任何对象,但是一旦不再需要它们就会被隐式删除。这种技术在C ++中通常被称为 Resource Allocation is Initialization(RAII) or Scope Bound Resource Management(SBRM)

您的每个对象( rowclt )都应该使用 RAII ,通过在这些原始指针上编写包装器或者更简单地使用随时可用的 Smart pointers

答案 1 :(得分:2)

智能指针是您所需要的。您应该将每个新Row放入std::shared_ptr<Row> row而不是指针;那些shared_ptr将在超出范围时自动清除(例如,当try-catch块退出时)。

你应该对'clt做些什么并不是那么明确......我很想将它存储在std::unique_ptr<Collection>中然后返回,因为很明显a)它会在某个时候被自动删除(可能是你的程序退出时)和b)调用代码很明显他们现在拥有get_records_from_db()返回的值,而不是Class2实例(或单例)它产生了它。

明确所有权语义是一件好事。