C ++内存泄漏与我的std :: map of& Objects和std :: vector of& Objects

时间:2016-01-24 23:11:51

标签: c++ object dictionary memory reference

基本上我有这个

std::map<std::string, Location&> exits = std::map<std::string, Location&>();

作为班级中的私人成员。我不确定当类的对象被删除时我将如何删除它以释放内存

我也有很多像这样的载体

std::vector<Item> Ritems;

我也不确定如何删除,矢量获取对象&amp;添加到它

Deleaker给了我大约1000个以下内容:

  

xmemory0,第89行(c:\ program files(x86)\ microsoft visual studio 14.0 \ vc \ include \ xmemory0)

位置对象

class Object;
class Location
{
    public:
        Location();
        Location(std::string RoomName, std::string RoomDesc);
        ~Location();
        Location(const Location& e);
        void AddExit(std::string Direction, Location &Room);
        void AddItem(Item &Items);
        void AddObject(Object &Objects);
        void RemoveObject(std::string ObjName);
        void AddNPC(NPC &NPCs);
        void PickUpItem(Character &CurChar, std::string ItemName);
        void DisplayAll();
        void DisplayExits();
        void DisplayItems();
        void DisplayObjects();
        void DisplayNPCs();
        std::string GetName();
        std::string GetDesc();
        Location GoCommand(std::string Direction);
        void TalkCommand(std::string Communication, Character &MainCharacter);
        Location operator=(const Location &other);
        Object CheckObject(std::string Command, std::string ObjName);
    private:
        std::string Name;
        std::string Description;

        std::map<std::string, Location&> exits = std::map<std::string, Location&>();

        std::vector<Item> Ritems;
        std::vector<Object> Robjects;
        std::vector<NPC> RNPC;
};

#include <iostream>
#include "Locations.h"  
#include <regex>
#include "Object.h"

Location::Location()
{
    Name = "";
    Description = "";
}
Location::Location(std::string RoomName, std::string RoomDesc)
{
    Name = RoomName;
    Description = RoomDesc;
}
Location::~Location()
{

}
Location::Location(const Location& e)
{
    Name = e.Name;
    Description = e.Description;
    exits = e.exits;
    Ritems = e.Ritems;
    Robjects = e.Robjects;
    RNPC = e.RNPC;
}
void Location::AddExit(std::string Direction, Location &Room)
{
    exits.insert(std::pair<std::string, Location*>(Direction, &Room));
}
void Location::AddItem(Item &Items)
{
    Ritems.push_back(Items);
}
void Location::AddObject(Object &Objects)
{
    Robjects.push_back(Objects);
}
void Location::RemoveObject(std::string ObjName)
{
    Object Temp;
    std::transform(ObjName.begin(), ObjName.end(), ObjName.begin(), ::tolower);
    for (int i = 0; i < Robjects.size(); i++)
    {
        std::string TempS = Robjects[i].GetName();
        std::transform(TempS.begin(), TempS.end(), TempS.begin(), ::tolower);
        if (TempS == ObjName)
            Robjects.erase(Robjects.begin() + i);
    }
}
void Location::AddNPC(NPC &NPCs)
{
    RNPC.push_back(NPCs);
}
void Location::PickUpItem(Character &CurChar, std::string ItemName)
{
    std::transform(ItemName.begin(), ItemName.end(), ItemName.begin(), ::tolower);

    for (int i = 0; i < Ritems.size(); i++)
    {
        std::string Temp = Ritems[i].GetName();
        std::transform(Temp.begin(), Temp.end(), Temp.begin(), ::tolower);
        if (Temp == ItemName)
        {
            CurChar.AddItem(Ritems[i]);
            Ritems.erase(Ritems.begin() + i);
        }
    }
}
Object Location::CheckObject(std::string Command, std::string ObjName)
{
    Object Temp;
    std::transform(Command.begin(), Command.end(), Command.begin(), ::tolower);
    std::transform(ObjName.begin(), ObjName.end(), ObjName.begin(), ::tolower);
    for (int i = 0; i < Robjects.size(); i++)
    {
        std::string TempS = Robjects[i].GetName();
        std::transform(TempS.begin(), TempS.end(), TempS.begin(), ::tolower);
        if (TempS == ObjName)
            return Robjects[i];
    }
    return Temp;
}
void Location::DisplayAll()
{
    WriteLine(7, '-');
    DisplayElement(7, Description);
    DisplayExits();
    DisplayItems();
    DisplayObjects();
    DisplayNPCs();
    WriteLine(7, '-');
}
void Location::DisplayExits()
{
    DisplayElement(7, "|- You can travel; ");

    for (std::map<std::string, Location*>::iterator ii = exits.begin(); ii != exits.end(); ++ii)
    {
        SetColour(7);
        std::cout << "\t";
        SetColour(112);
        std::cout << "[" << (*ii).first << "]";
        SetColour(8);
        std::cout << " to " << (*ii).second->GetName() << std::endl;
    }
}
void Location::DisplayItems()
{
    int Count = 0;
    if (Ritems.size() != 0)
    {
        DisplayElement(7, "Items in room: ");
        for (int i = 0; i < Ritems.size(); i++)
        {
            DisplayElementWC(Count, 5, 13, Ritems[i].GetName());
            DisplayElementWC(Count, 6, 14, Ritems[i].GetDesc());
            DisplayElementWC(Count, 6, 14, Ritems[i].GetItemValue());
            Count++;
        }
    }
}
void Location::DisplayObjects()
{
    int Count = 0;
    if (Robjects.size() != 0)
    {
        DisplayElement(7, "Objects in room: ");
        for (int i = 0; i < Robjects.size(); i++)
        {
            DisplayElementWC(Count, 5, 13, Robjects[i].GetName());
            DisplayElementWC(Count, 6, 14, Robjects[i].GetDesc());
        }
    }
}
void Location::DisplayNPCs()
{
    int Count = 0;
    if (RNPC.size() != 0)
    {
        DisplayElement(7, "NPCs in room: ");
        for (int i = 0; i < RNPC.size(); i++)
        {
            DisplayElementWC(Count, 5, 13, RNPC[i].GetName());
            DisplayElementWC(Count, 6, 14, RNPC[i].GetDesc());
        }
    }
}
std::string Location::GetName()
{
    return Name;
}
std::string Location::GetDesc()
{
    return Description;
}

Location Location::GoCommand(std::string Direction)
{
    Location ReturnLoc = *this;
    std::string Test;
    std::transform(Direction.begin(), Direction.end(), Direction.begin(), ::tolower);
    for (std::map<std::string, Location*>::iterator ii = exits.begin(); ii != exits.end(); ++ii)
    {
        Test = (*ii).first;
        std::transform(Test.begin(), Test.end(), Test.begin(), ::tolower);
        if (Test == Direction)
            ReturnLoc = *(*ii).second;
    }
    return ReturnLoc;
}
void Location::TalkCommand(std::string Communication, Character &MainCharacter)
{
    std::string Test;
    std::transform(Communication.begin(), Communication.end(), Communication.begin(), ::tolower);
    for (int i = 0; i < RNPC.size(); i++)
    {
        Test = RNPC[i].GetName();
        std::transform(Test.begin(), Test.end(), Test.begin(), ::tolower);
        if (Test == Communication)
        {
            RNPC[i].StartConvo(MainCharacter);
        }
    }
}
Location Location::operator=(const Location &other)
{
    Name = other.Name;
    Description = other.Description;
    exits = other.exits;
    Ritems = other.Ritems;
    Robjects = other.Robjects;
    RNPC = other.RNPC;
    return *this;
}

好的,我希望这是一个MCVE aha

#include <iostream>
#include <map>
#include <regex>
#include <string>
#include <windows.h>
#include <cctype>
//Custom Classes

class Location;
class UpdateLocation
{
public:
    UpdateLocation();
    ~UpdateLocation();
    void AddLocation(Location &Room);
    void UpdateNow(Location &Room);
    Location GetLocal(Location &Room);

private:
    std::map<std::string, Location*> Locations = std::map<std::string, Location*>();
};

class Location
{
public:
    Location();
    Location(std::string RoomName, std::string RoomDesc);
    ~Location();
    Location(const Location& e);
    void AddExit(std::string Direction, Location &Room);
    void DisplayExits();
    std::string GetName();
    std::string GetDesc();
    Location operator=(const Location &other);
private:
    std::string Name;
    std::string Description;

    std::map<std::string, Location*> exits = std::map<std::string, Location*>();
};

UpdateLocation::UpdateLocation()
{

}
UpdateLocation::~UpdateLocation()
{

}
void UpdateLocation::AddLocation(Location &Room)
{
    Locations.insert(std::pair<std::string, Location*>(Room.GetName(), &Room));
}
void UpdateLocation::UpdateNow(Location &Room)
{
    for (std::map<std::string, Location*>::iterator ii = Locations.begin(); ii != Locations.end(); ++ii)
    {
        if ((*ii).first == Room.GetName())
        {
            *(*ii).second = Room;
        }
    }
}
Location UpdateLocation::GetLocal(Location &Room)
{
    for (std::map<std::string, Location*>::iterator ii = Locations.begin(); ii != Locations.end(); ++ii)
    {
        if ((*ii).first == Room.GetName())
        {
            return *(*ii).second;
        }
    }
}

Location::Location()
{
    Name = "";
    Description = "";
}
Location::Location(std::string RoomName, std::string RoomDesc)
{
    Name = RoomName;
    Description = RoomDesc;
}
Location::~Location()
{

}
Location::Location(const Location& e)
{
    Name = e.Name;
    Description = e.Description;
    exits = e.exits;

}
void Location::AddExit(std::string Direction, Location &Room)
{
    exits.insert(std::pair<std::string, Location*>(Direction, &Room));
}
void Location::DisplayExits()
{
    std::cout << "|- You can travel; " << std::endl;

    for (std::map<std::string, Location*>::iterator ii = exits.begin(); ii != exits.end(); ++ii)
    {
        std::cout << "\t";
        std::cout << "[" << (*ii).first << "]";
        std::cout << " to " << (*ii).second->GetName() << std::endl;
    }
}
std::string Location::GetName()
{
    return Name;
}
std::string Location::GetDesc()
{
    return Description;
}
Location Location::operator=(const Location &other)
{
    Name = other.Name;
    Description = other.Description;
    exits = other.exits;
    return *this;
}

void main()
{
    //Create GameWorld
    UpdateLocation UpdateIt;
    Location HallWay("Hallway", "Long corridor with a wide array of footboats");

    getchar();
    getchar();
}

1 个答案:

答案 0 :(得分:3)

首先,您可能想要阅读此内容(对于c ++ 03及更早版本):

Why Can't I store references in an STL map in C++?

对于c ++ 11及更高版本,它实际上可以使用std::mapstd::map::emplace() s中将引用作为值,但它不方便,我不能看到它像原始指针一样有用,它也应该如果容器对象拥有放置在其中的对象,则替换为std::unique_ptr

你可能想要

std::map<std::string, Location *> exits;

作为您的私人会员。您无需删除地图或矢量图。调用类的析构函数时,将调用相应对象的析构函数。它们基本上是自毁的。您解释说exits对象不拥有Location个对象,因此exits与释放为其分配的内存不应该有任何关系。