2

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

子弹管理器.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;
};

子弹管理器.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 一次 -> 内存使用量略有增加
  • 之后调用 EraseAllBullets -> 内存使用量根本没有下降!
  • 多次调用 AddBullet -> 显着增加内存使用量
  • 之后调用 EraseAllBullets -> 大部分内存被释放,但不是全部!

效果不是很大,而且似乎变慢了——程序开始时使用 10MB 的 RAM,在只使用这两个函数一段时间后,每个向量清除后,内存使用量仅下降到 15-20MB。

难道我做错了什么?即使这应该发生,我仍然希望能够释放我分配的所有内存。

4

2 回答 2

4

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

于 2013-06-28T17:27:03.103 回答
2

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

您观察到的行为可能来自两个完全不同的事物:

  • std::vector::clear()只是应该删除向量中包含的对象,而不是实际释放向量本身的内存。正如cppreference.com所说:“许多实现在调用 后不会释放分配的内存clear(),实际上保持capacity()向量不变。 ”您可以通过使用而不是解决这个特定问题:将新的临时空向量与你的,有效地释放你使用的所有内存。std::vector<...>().swap(vectorToClear);clear()

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

于 2013-06-28T17:31:24.787 回答