静态映射中动态分配的对象.删除必要的

Dynamically allocated objects in static map. Delete necessary?

本文关键字:删除 对象 静态 动态分配 映射      更新时间:2023-10-16

考虑以下人为的例子:

class AllocatedClass {
public:
   AllocatedClass() : dummy(0) {}
private:
  int dummy;
};
class AllocatingClass {
public:
     AllocatingClass() : list() {}
     ~AllocatingClass() {
        // CANNOT delete the elements in list here because there may
        // be more than on instance of AllocatingClass sharing the same
        // static list 
     }
     AddNewObject() {
        list.push_back(new AllocatedClass());
     }
private:
     static std::vector<AllocatedClass*> list;
};

在实施文件中

std::vector<AllocatedClass*> AllocatingClass::list;

撇开一个类的多个实例是否应该共享动态分配对象的列表是一个好主意,有没有办法在程序结束时清理这些新的 AlatedClass 对象? 考虑到我不想在应用程序结束之前删除它们,如果这些永远不会被删除,这有关系吗?

如果对象的生存期是程序执行的生存期,则无需用代码释放内存。内存将自动释放。

出于性能原因,许多 Linux 命令行工具不会释放代码中的内存。(自动释放内存页比逐个释放每个对象更快。

另一种策略是保留一个单独的唯一 AlatedClass 实例列表,然后稍后将它们从该列表中释放出来(切换对象的所有权)。喜欢std::list<AllocatedClass*> to_be_freed.

有没有办法在最后清理这些新的分配类对象 的程序?

一种解决方案是使用 std::shared_ptr 并自动完成释放。

#include <memory>
#include <vector>
#include <iostream>
class AllocatedClass 
{
    public:
       AllocatedClass(int n = 0) : dummy(n) {}
       ~AllocatedClass() { std::cout << "I am being destroyed" << 'n'; }
    private:
       int dummy;
};
class AllocatingClass 
{
    public:
         AllocatingClass() {}
         void AddNewObject(int num = 0) 
         {  shared_list.push_back(std::make_shared<AllocatedClass>(num)); }
    private:
         static std::vector<std::shared_ptr<AllocatedClass>> shared_list;
};
std::vector<std::shared_ptr<AllocatedClass>> AllocatingClass::shared_list;
AllocatingClass ac;
int main()
{
    ac.AddNewObject();
    ac.AddNewObject(1);
}

现场示例

请注意,对于放置在向量中的对象,将自动调用析构函数。

(顺便说一句,将成员变量命名为 list 不是一个好主意)。

大多数时候(非常接近所有时间),创建动态分配对象的对象应该有一个程序员定义的析构函数,以便在对象达到其生命周期结束时释放内存。 AllocatingClass应该有一个析构函数,因为您使用 new 分配动态内存。

~AllocatingClass() {
    for (int i = 0 ; i < list.size();i++) {
        if(list[i] != NULL) {
            delete list[i];
            list[i] = NULL;
        }
}

这应该既提供取消分配内存的方法,又提供安全性,以便您不会删除已删除的指针。