2014-12-27 56 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::~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 2014-12-27 16:39:07

+0

@nvoigt但我會如何改變我的設計呢? – andre 2014-12-27 16:55:32

+0

**編輯**您的文章幷包含您收到的_exact_錯誤消息以及使用哪種工具發佈錯誤(編譯器,valgrind,Visual Leak Detector等)。 – 2014-12-27 18:39:55

回答

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代替列表中的原始指針可以解決您的問題(輕微的性能損失)。