2014-12-27 2 views
1

У меня есть класс пули. и я пытаюсь создать его следующим кодом:Память в использовании проблема с использованием мармелада SDK

Я всегда получаю утверждение, что есть память, которая используется .. почему?

В другом классе под названием корабля:

if (g_Input.isKeyDown(s3eKeySpace))// && Canfire) 
     { 
      Bullet *bullet = new Bullet(); 
      bullet->Init(SHIP_BULLET); 
      bullet->setPosition(Position.x, Position.y - 20); 
      Bullets->push_back(bullet); 
      Canfire = false; 

     } 

Это называется каждый кадр, который вызывает память до сих пор в использовании:

for (list<Bullet*>::iterator it = Bullets->begin(); it != Bullets->end();) 
{ 
    (*it)->Update(dt); 

    if ((*it)->IsDestroyed) 
    { 
     Canfire = true; 
     it = Bullets->erase(it); 
    } 
    else 
    { 
     it++; 
     Canfire = false; 

    } 

} 

деструктор кораблей класса

Ship::~Ship() 
{ 
    for (std::list<Bullet*>::iterator it = Bullets->begin(); it != Bullets->end(); ++it) 
     delete *it; 
    delete Bullets; 

} 

class Bullet 
{ 
public: 
    Bullet(); 
    ~Bullet(); 
public: 
    void Init(BulletTypes bulletType); 
    void Update(float dt); 
    void Render(); 
    CIw2DImage*  Image;    // curr image 
} 

void Bullet::Init(BulletTypes bulletType) 
{ 
    BulletType = bulletType; 
    if (BulletType == SHIP_BULLET) 
    { 
     Image = Iw2DCreateImage("textures/ship_bullet.png"); 
     if (Image == nullptr) 
     return; 

    } 
} 
Bullet::~Bullet() 
{ 
    delete Image; 
} 
+0

Вы действительно должны загружать изображение для пули только * один раз *, а не один раз за пулю. – nvoigt

+0

@nvoigt, но как я могу изменить свой дизайн, чтобы сделать это? – andre

+0

** Редактируйте ** свое сообщение и укажите сообщение об ошибке _exact_, которое вы получаете, и какой инструмент выдает ошибку (компилятор, valgrind, визуальный детектор утечек и т. Д.). –

ответ

0

Исполнительной этот код вызывает утечку:

for (list<Bullet*>::iterator it = Bullets->begin(); it != Bullets->end();) 
{ 
    (*it)->Update(dt); 

    if ((*it)->IsDestroyed) 
    { 
     Canfire = true; 
     it = Bullets->erase(it); 
    } 
    else 
    { 
     it++; 
     Canfire = false; 
    } 
} 

Что происходит, в основном, вы удаляете динамически выделенный элемент из контейнера, теряя при этом любую ссылку на него, поэтому вы больше не можете освобождать свою память. Очевидно, что вызов дескриптора Ship освобождает элементы, которые в данный момент находятся в списке, исключая те, которые были удалены на итерации.

Я предлагаю это как исправить:

for (list<Bullet*>::iterator it = Bullets->begin(); it != Bullets->end();) 
{ 
    (*it)->Update(dt); 

    if ((*it)->IsDestroyed) 
    { 
     Canfire = true; 
     delete *it; // it now points to invalid address 
     it = Bullets->erase(it); 
    } 
    else 
    { 
     it++; 
     Canfire = false; 
    } 
} 

Другим вариантом было бы хранить все снятые пули в какой-либо другой контейнер в классе Корабль в случае, когда пуля может ссылаться после того, как он был разрушен. Проблема с этой идеей заключается в том, что у вас много уничтоженных пуль, занимающих память, и вам нужно решить, как их удалить, как только они действительно окажутся бесполезными.

Если вы застряли в этом, использование std :: shared_ptrs вместо необработанных указателей в списке может решить вашу проблему (для небольшого снижения производительности).

Смежные вопросы