vector加上unique_ptr到一个对象,内存没有被释放?

时间:2013-06-28 17:21:24

标签: c++ vector unique-ptr

所以,我正在尝试将向量与智能指针一起使用,以便更轻松地进行内存管理,而且......好吧,我遇到了问题。 那是我的代码的(大大缩短的)版本:

bulletManager.h:

class BulletManager
{
    public:
        BulletManager();
        virtual ~BulletManager();

        void AddBullet(int type, double x, double y, double vx, double vy);
        void EraseAllBullets();
    protected:
    private:
        std::vector<std::unique_ptr<Bullet>> bullets;
};

bulletManager.cpp:

BulletManager::BulletManager()
{
    bullets.reserve(50000);
}
void BulletManager::AddBullet(int type, double x, double y, double vx, double vy)
{
    for(int i=0;i<1000;i++) bullets.push_back(std::unique_ptr<BasicBullet>(new BasicBullet(type, x, y, vx, vy)));
}
void BulletManager::EraseAllBullets()
{
    bullets.clear();
}

BasicBullet类是抽象Bullet类的子类。 为了更容易看到内存使用情况的变化,我已经让AddBullet函数生成了1000个对象,并在子弹类中添加了“char tab [10000]”。

现在,发生的事情(根据任务管理器)是:

  • 调用AddBullet一次 - &gt;内存使用量略有增加
  • 之后调用EraseAllBullets - &gt;内存使用量根本没有下降!
  • 多次调用AddBullet - &gt;显着的内存使用量增加
  • 之后调用EraseAllBullets - &gt;大多数记忆都被释放了,但不是全部!

效果不是很大并且似乎变慢 - 程序以10MB的RAM使用开始,并且仅使用这两个功能一段时间后,每个向量清除内存使用量仅下降到15-20MB。 / p>

我做错了吗?即使这应该发生,如果我能够释放我已经分配的所有内存,我仍然会更喜欢。

2 个答案:

答案 0 :(得分:3)

您不能依赖任务管理器来告诉您应用程序已分配/可用的内存量。释放内存时,它可能会被C ++运行时中的池回收,以供应用程序稍后重用,而不是返回到操作系统。

答案 1 :(得分:2)

你没有做错什么,你只是做错了假设。

您所观察到的行为可能来自两个截然不同的行为:

  • std::vector::clear()只能删除向量中包含的对象,而不是实际释放向量本身的内存。正如cppreference.com所说:“许多实现在调用clear()后不会释放已分配的内存,实际上会使向量的capacity()保持不变。您可以使用std::vector<...>().swap(vectorToClear);代替clear()处理此特定问题:与您交换新的临时空矢量,有效释放您使用的所有内存。

  • C ++的delete运算符不一定会将内存返回给系统。它只是释放内存,以便new再次使用它,同样不需要系统获取内存。该行为没有解决方法,它取决于您的运行时(即编译器)。