0

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

   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->a ,因为它是在堆中分配的?
  2. 对于其他成员,它们将被自动删除,因为它们在堆栈中。
4

4 回答 4

2

经验法则:如果你有一个new,你必须有一个对应的delete。与 malloc 和 C 中的 free 相同。

于 2013-01-30T09:41:51.030 回答
1

您需要手动删除所有由new operator. 否则你有潜在的内存泄漏,因为你没有删除A* a;

newdelete,new []并且delete []应该始终成对使用。

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

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

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

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

m_vector.erase(std::remove_if(m_vector.begin(), m_vector.end(), 
               [](std::unique_ptr<tStruct>& up){ return up->id == ID; }), 
               m_vector.end());
于 2013-01-30T09:50:48.573 回答
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);
    }
}
于 2013-01-30T09:49:24.583 回答
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));

不需要特殊的删除代码。

于 2013-01-30T09:51:58.637 回答