处理内存时,使用std :: vector

时间:2014-02-24 15:52:20

标签: c++ memory vector memory-leaks scoping

我正在使用带有我自己的类类型的vector:

std::vector<CItem> m_vItems;

在我的班级中,我正在初始化SFML类型,如纹理和精灵:

class CItem
{
    (...)
    sf::Texture m_Texture;
    sf::Sprite m_Sprite;
    sf::IntRect* m_pRect;
    (...)
}

我正在尝试将对象传递给我声明为其他类CLevel成员的向量,我正在这个类的方法中这样做:

CItem *temp = new CItem(x, y, kind);
m_vItems.push_back(*temp);

如您所见,我不是用temp删除delete指针,但在类CLevel的析构函数中,我有一个简单的行:

std::vector<CItem>().swap(m_vItems);

我对内存泄漏感到困惑。我的程序是否有其中一些或以上解决问题的行,我的示例已正确编写?

5 个答案:

答案 0 :(得分:2)

您的程序在没有匹配new的情况下调用delete,并且没有将new的结果传递给其他将为您管理的类。因此,您的程序有内存泄漏。

使用m_vItems.push_back(CItem(x, y, kind));代替您提供的两行示例有问题吗?

答案 1 :(得分:1)

CItem *temp = new CItem(x, y, kind);
m_vItems.push_back(*temp); // here a copy of *temp is pushed into vector

您应该在某处调用delete来删除您使用temp分配的内容:

delete temp;

避免内存泄漏。对new的任何调用都必须在某处与delete进行匹配调用。这不会影响被推入矢量的临时副本。只要载体存在,它仍然存在。

最好只使用:

m_vItems.push_back(CItem(x, y, kind)); // implement this constructor correctly
                                       // to avoid uninitialized variables

当您关注泄漏时,您可以使用工具来描述您的程序:Valgrind或Visual Leak Detector。

答案 2 :(得分:0)

如果您使用的是Windows平台,则可以使用CRT库检测特定代码部分是否有任何泄漏。这个link解释了如何在VS 2012中实现它,它也适用于早期版本。

答案 3 :(得分:0)

假设您需要保留一个指针向量,而不是CItems的向量,我会使用智能指针来管理对象的生命周期。 shared_ptr易于使用:

shared_ptr<CItem*> temp(new CItem(x,y,z));
m_vItems.push_back(temp);

当向量移动时,CItem将被正确清理。当项目被传递时,它们也将被正确处理 - 没有内存泄漏。

答案 4 :(得分:0)

内存泄漏是指在堆上分配空间(在您的情况下通过调用new)并且对该内存的引用丢失。换句话说,您无法通过调用delete来回收内存。如果使用swap将指针从一个向量移动到另一个向量,那么从技术上讲,这不是泄漏,因为你仍然可以引用另一个向量中的内存,你仍然可以调用delete。

请记住最终调用删除。在某些情况下可能很诱人,具体取决于使用方法,以便稍后让系统清理,而不是删除内存,例如:如果代码是CGI。但是,当代码用于最初没有预料到的用例时,例如,这可能会导致问题。从长期运行的框架中调用的单元测试。通常值得花时间立即对删除进行编码,即使这样做与即时目标没有关系,也不要让自己处于可能需要回圈并稍后尝试修复的位置。