2016-08-19 10 views
-1

メモリリークに問題があります。 "Deleaker"というプログラムでテストしました。 デストラクタの内容をコメントアウトすると、これらのメモリリークを正しく処理しています。 ありがとうございました。クラス内のメモリリーク

Inventory.h

#ifndef INVENTORY_H 
#define INVENTORY_H 

#include "Item.h" 

class InventoryOfItems { 
public: 
    InventoryOfItems(int c = 10); 
    ~InventoryOfItems(); 

    bool Add(Item* newItem); 
    Item* Remove(int itemIndex); 
    int Size() const; 
    int Items() const; 
    int Weapons() const; 
    int Potions() const; 
    Item::item_t GetItemType(int invIndex) const; 

    void DisplayWeapons(); 
    void DisplayPotions(); 
    void DisplayInfo(); 
private: 
    Item** items; 
    int itemCount; 
    int capacity; 
}; 

#endif /* INVENTORY_H */ 

Inventory.cpp

#include "Inventory.h" 
#include "Weapon.h" 
#include "Potion.h" 

#include <iostream> 
using std::cout; 
using std::endl; 

#include <iomanip> 
using std::setw; 
using std::setiosflags; 
using std::ios; 

#include <string> 

InventoryOfItems::InventoryOfItems(int cap) { 
    itemCount = 0; 
    capacity = cap; 
    items = new Item*[capacity]; 

    for (int i = 0; i < capacity; i++) { 
     items[i] = 0; 
    } 
} 

InventoryOfItems::~InventoryOfItems() { 

    for (int i = 0; i < itemCount; i++) { 
     delete items[i]; 
    } 

    delete [] items; 
} 

bool InventoryOfItems::Add(Item* newItem) { 
    if (newItem == 0) 
     return false; 

    for (int i = 0; i < capacity; i++) 
     if (items[i] == 0) { // empty 
      switch (newItem->GetType()) { 

       case Item::Weapon: 
       { 

        Weapon* originalWeapon = (Weapon*) newItem; 
        Weapon* newWeapon = new Weapon(originalWeapon); 

        items[i] = newWeapon; 
        itemCount++; 
        break; 
       } 
       case Item::Potion: 
       { 
        Potion* originalPotion = (Potion*) newItem; 
        Potion* newPotion = new Potion(originalPotion); 
        items[i] = newPotion; 
        itemCount++; 
        break; 
       } 
      } 
      return true; 
     } 

    return false; 
} 

Item* InventoryOfItems::Remove(int itemIndex) { 
    if (items[itemIndex - 1] == 0) 
     return 0; 
    else { 
     Item* itemToReturn; 
     itemToReturn = items[itemIndex - 1]; 
     items[itemIndex - 1] = 0; 
     itemCount--; 
     return itemToReturn; 
    } 
} 

int InventoryOfItems::Size() const { 
    return capacity; 
} 

int InventoryOfItems::Items() const { 
    return itemCount; 
} 

int InventoryOfItems::Weapons() const { 
    int count = 0; 
    for (int i = 0; i < capacity; i++) 
     if (items[i] != 0) 
      if (items[i]->GetType() == Item::Weapon) 
       count++; 

    return count; 
} 

int InventoryOfItems::Potions() const { 
    int count = 0; 
    for (int i = 0; i < capacity; i++) 
     if (items[i] != 0) 
      if (items[i]->GetType() == Item::Potion) 
       count++; 

    return count; 
} 

Item::item_t InventoryOfItems::GetItemType(int invIndex) const { 
    if (items[invIndex - 1] == 0) 
     return Item::Undefined; 
    else 
     return items[invIndex - 1]->GetType(); 
} 

void InventoryOfItems::DisplayWeapons() { 
    cout << " WEAPONS" << endl; 
    for (int i = 0; i < capacity; i++) 
     if (items[i] != NULL) 
      if (items[i]->GetType() == Item::Weapon) { 
       cout << " " << setiosflags(ios::right) << setw(2) << i + 1 << ": "; 
       items[i]->DisplayInfo(); 
       cout << endl; 
      } 
} 

void InventoryOfItems::DisplayPotions() { 
    cout << " POTIONS" << endl; 
    for (int i = 0; i < capacity; i++) 
     if (items[i] != NULL) 
      if (items[i]->GetType() == Item::Potion) { 
       cout << " " << setiosflags(ios::right) << setw(2) << i + 1 << ": "; 
       items[i]->DisplayInfo(); 
       cout << endl; 
      } 
} 

void InventoryOfItems::DisplayInfo() { 
    cout << endl; 
    cout << " ----------------------------------" << endl; 
    cout << " Inventory (carrying " << itemCount << " of " << capacity << " items)" << endl; 
    cout << " ----------------------------------" << endl; 

    DisplayWeapons(); 
    DisplayPotions(); 
} 

削除コール:

void Hero::equip() 
{ 
    int item = 0; 

    if(inv.Items() == 0) 
    { 
     cout << "Your inventory is empty!" << endl; 
    } 
    else 
    { 
     inv.DisplayWeapons(); 
     cout << "Choose a weapon: " << endl; 
     cin >> item; 

     if(weapon != NULL) 
     { 
      inv.Add(weapon); 
     } 

     Weapon *selected = (Weapon*) inv.Remove(item); 
     weapon = new Weapon(selected); 
     delete selected; 
    } 
} 

武器は「武器へのポインタ(英雄の手)

+2

3/5/0のルールを見てください。 – Jarod42

+1

デストラクタにコメントしないと問題はありますか? – Mike

+3

'std :: vector >'を使うべきでしょう。 – Jarod42

答えて

0

あなたがあります再ありません上書きする前に-ing weapon。追加した行に注意してください。

inv.DisplayWeapons(); 
    cout << "Choose a weapon: " << endl; 
    cin >> item; 

    if(weapon != NULL) 
    { 
     inv.Add(weapon); 
     delete weapon; // Added 
    } 

    Weapon *selected = (Weapon*) inv.Remove(item); 
    weapon = new Weapon(selected); // `weapon` would be overwritten here 
    delete selected; 

は、我々は質問のコメントで言ったようにメモリ管理をめちゃくちゃにすることは簡単ですので、私はまた、すべてのこれらのポインタの代わりに std::vectorを使用することをお勧めします、と述べました。

+0

私はクラスヒーローのデストラクタで削除武器を持っています –

+0

「ヒーロー」が破壊された場合にのみ呼び出されます。 'Hero :: equip()'の中から破壊されていません。デストラクタは、オブジェクトが削除されるかスコープから外れるときに呼び出されます。あなたは 'Hero'オブジェクトを削除しておらず、それ自身の機能の範囲外に出ることもありません。 –

+0

そのインベントリデストラクタにはまだ問題があります。私はその作業をコメントするときに、オブジェクトに対してエラーが発生した場合はどうすればいいですか? そして、私はベクトルだけを使用します。単にベクトルで書き直そうとしています。 ..:/ –

関連する問題