代码之家  ›  专栏  ›  技术社区  ›  Max Frai

代码需要太多内存

  •  0
  • Max Frai  · 技术社区  · 15 年前

    class EnvironObject
    {
       protected:
          vector<float> mX, mY, mXSpeed, mYSpeed;
          int mMaxObjects;
    
       public:
          virtual void init(int maxObjects);
          virtual void setLimit(int limit);
          virtual int getLimit();
          virtual void update(float arg) = 0;
    };
    
    void EnvironObject::setLimit(int limit)
    {
       mMaxObjects = limit;
    
       mX.resize(limit, 0); mY.resize(limit, 0);
       mXSpeed.resize(limit, 0); mY.resize(limit, 0);
    }
    
    int EnvironObject::getLimit()
    {
       return mMaxObjects;
    }
    
    void EnvironObject::init(int maxObjects)
    {
        mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects);
    
        fill(mX.begin(), mX.end(), 0);
        fill(mY.begin(), mY.end(), 0);
        fill(mXSpeed.begin(), mXSpeed.end(), 0);
        fill(mYSpeed.begin(), mYSpeed.end(), 0);
    
        /*mX.reserve(mMaxObjects * 1.5); mY.reserve(mMaxObjects * 1.5);
        mXSpeed.reserve(mMaxObjects * 1.5); mYSpeed.reserve(mMaxObjects * 1.5);*/
    
        mMaxObjects = maxObjects;
    }
    

    这是一些基本类,现在是用法:

    class Rain : public EnvironObject
    {
        public:
            Rain(int maxDrops = 150);
            void update(float windPower);
    };
    
    Rain::Rain(int maxDrops)
    {
        srand(time(NULL));
    
        IEnvironObject::init(maxDrops);
    }
    
    void Rain::update(float windPower)
    {
        for (int i=0; i < mMaxObjects; i++)
        {
           mX[i] += mXSpeed[i];
           mY[i] += mYSpeed[i];
    
           mXSpeed[i] += windPower;
           mYSpeed[i] += G;
    
       // Drawing
        }
    }
    

    对象 Rain 使用默认构造函数创建(因此,每个数组的大小为150个元素),然后我调用 setLimit(50) . 问题是代码几乎每次运行都会失败,但有一个例外:

    terminate called after throwing an instance of 'std::bad_alloc'
    

    有时它会在线路上分段:

    mY[i] += mYSpeed[i];
    

    我无法想象它会是什么,因为代码太旧了,而且工作正常。新的只是基类。

    当我在启动应用程序时查看内存使用情况时,我看到几乎+600MB!

    4 回复  |  直到 15 年前
        1
  •  7
  •   sbi    15 年前

    再看看你的功能:

    void EnvironObject::init(int maxObjects)
    {
        mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects);
        //                                               ^
        // ...
    
        mMaxObjects = maxObjects;
    }
    

    您使用的是尚未初始化的变量。

    你班上的一个大问题是你在做所谓的两阶段结构。你的班级 EnvironObject 具有编译器提供的默认构造函数,该构造函数为所有POD类型创建具有随机值的对象( mMaxObjects init() 方法来真正初始化对象。但这就是构装师的目的!

    void EnvironObject::EnvironObject(int maxObjects)
      : mMaxObjects(maxObjects)
      , mX(maxObjects), mY(maxObjects), mXSpeed(maxObjects), mYSpeed(maxObjects)
    {
        /* these aren't necessary, std::vector automatically does this
        fill(mX.begin(), mX.end(), 0);
        fill(mY.begin(), mY.end(), 0);
        fill(mXSpeed.begin(), mXSpeed.end(), 0);
        fill(mYSpeed.begin(), mYSpeed.end(), 0);
        */
    }
    

    派生类可以使用此构造函数:

    Rain::Rain(int maxDrops)
     : EnvironObject(maxDrops)
    {
        srand(time(NULL));
    }
    

    mY[i] += mYSpeed[i] :

    当您通过指向任何地方的指针调用此函数时,可能会发生这种情况。

        2
  •  5
  •   user180326 user180326    15 年前

    init() 在初始化之前。所以它有一个随机值。

    void EnvironObject::init(int maxObjects) 
    { 
       mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects);  // you mean maxObjects here
    
        3
  •  4
  •   extraneon    15 年前

    我想你想替换

    void EnvironObject::init(int maxObjects)
    {
        mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects);
    

    具有

    void EnvironObject::init(int maxObjects)
    {
        mX = mY = mXSpeed = mYSpeed = std::vector<float>(maxObjects);
    

    请注意,在矢量创建中,mMaxObject被替换为maxObjects。

        4
  •  4
  •   Reinderien    15 年前

    一个注释是,虽然它不太可能修复您的内存错误,但是由于字段mX、mY、mXSpeed和mYSpeed似乎是相关的,而且向量的大小都是相同的,所以您应该考虑将它们合并为一个包含四个成员的结构,并且有一个包含其中几个结构实例的向量。