正确的struct内存管理

时间:2013-01-30 09:37:22

标签: c++

我想确保不会发生内存泄漏。

   struct tStruct{
       uint32_t id;
       A* a;
       C b;
   };
   std::vector<tStruct*> m_vector;

我按照方式将对象推送到矢量中。

推动:

tStruct* myStruct = new tStruct;
myStruct->id = ID; // Some unique value
myStruct->a= new A();
myStruct->b = c; // c is an object
m_vector.push_back(myStruct);

擦除:

 // Some stuff here 
 for (uint32_t i = 0; i < m_vector.size(); i++) {
     if (m_vector.at(i)->id == ID) { // Some filtering
         delete m_vector.at(i);
         m_vector.erase(m_vector.begin() + i);
     }
 }

我是否理解正确

  1. 我需要删除myStruct-&gt;,因为它在堆中分配了吗?
  2. 对于其他成员,它们将在堆叠时自动删除。

4 个答案:

答案 0 :(得分:2)

经验法则:如果您有new,则必须有相应的delete。与malloc相同,在C中免费。

答案 1 :(得分:1)

您需要手动删除由new operator创建的所有动态分配的对象。否则您有潜在的内存泄漏,因为您尚未删除A* a;

newdeletenew []delete []应始终成对使用。

更好的解决方案是使用智能指针:

struct tStruct
{
     uint32_t id;
     std::unique_ptr<A> a;
     C b;
};

std::vector<std::unique_ptr<tStruct>> m_vector;

使用erase remove idiom从vector中删除项目:

m_vector.erase(std::remove_if(m_vector.begin(), m_vector.end(), 
               [](std::unique_ptr<tStruct>& up){ return up->id == ID; }), 
               m_vector.end());

答案 2 :(得分:0)

每次使用new在堆中创建对象时,某处都必须有相应的delete。否则你将泄漏资源(在这种情况下是内存)。

但是,一般来说(这适用于您的示例),您可以做的最好的事情是使用辅助类来管理这些资源。在你的情况下,一个智能指针。在C ++ 11中,标准库提供了std::shared_ptr<>,它看起来像是适合您情况的智能指针:

struct tStruct{
    uint32_t id;
    std::shared_ptr<A> a;
    C b;
};
std::vector<std::shared_ptr<tStruct>> m_vector;

创建智能指针与创建原始指针没有太大区别:

std::shared_ptr<tStruct> myStruct (new tStruct);
myStruct->id = ID; // Some unique value
myStruct->a.reset(new A());
myStruct->b = c; // c is an object
m_vector.push_back(myStruct);

但是现在你可以忘记调用delete,因为std::shared_ptr<>会处理这个问题:

// Some stuff here 
for (uint32_t i = 0; i < m_vector.size(); i++) {
    if (m_vector.at(i)->id == ID) { // Some filtering
        // delete m_vector.at(i); This is no longer needed
        m_vector.erase(m_vector.begin() + i);
    }
}

答案 3 :(得分:0)

您的代码仍包含多个内存泄漏。如果推送对象失败,您的推送代码没有任何回滚:

tStruct* myStruct = new tStruct;
myStruct->id = ID;
myStruct->a= new A(); //could throw, if it does, then `myStruct` will leak
myStruct->b = c; // c is an object
//could throw, if it does, then `myStruct` and `myStruct->a` will leak
m_vector.push_back(myStruct);

通常,对delete的任何手动调用都表示您的代码泄漏或过于复杂。为了使代码不泄漏,您应该使用智能指针:

 struct tStruct{
    uint32_t id;
    std::unique_ptr<A> a;
    C b;
};
std::vector<std::unique_ptr<tStruct>> m_vector;

构建:

std::unique_ptr<tStruct> myStruct(new tStruct);
myStruct->id = ID;
myStruct->a.reset(new A());
myStruct->b = c; // c is an object
m_vector.push_back(std::move(myStruct));

不需要特殊的删除代码。