Код требует слишком много памяти - PullRequest
0 голосов
/ 20 октября 2010

Я портирую некоторый код в другую структуру:

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];

Я не могу представить, что бы это могло быть, потому что код старый и он работал. Новый только базовый класс.

И когда я смотрю на использование ОЗУ при запуске приложения, я вижу почти +600 МБ!

Ответы [ 4 ]

7 голосов
/ 20 октября 2010

Посмотрите еще раз на свою функцию:

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]:

Это может произойти, когда вы вызываете эту функцию через указатель, указывающий в никуда.

5 голосов
/ 20 октября 2010

Вы используете mMaxObjects в init() перед его инициализацией. Так что оно имеет случайное значение.

void EnvironObject::init(int maxObjects) 
{ 
   mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects);  // you mean maxObjects here
4 голосов
/ 20 октября 2010

Один комментарий, хотя он вряд ли исправит вашу ошибку памяти, состоит в том, что, поскольку поля mX, mY, mXSpeed ​​и mYSpeed ​​кажутся связанными, а векторы имеют одинаковый размер, вам следует рассмотреть возможность объединения их в одну структуру счетыре члена и имеющие один вектор, содержащий несколько таких экземпляров структуры.

4 голосов
/ 20 октября 2010

Я думаю, вы хотите заменить

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 при создании вектора.

...