c ++ std :: map删除指针

时间:2018-09-10 22:28:04

标签: c++ dictionary std free

我将在下面链接这些类和执行的输出。

问题是std::map正在遍历,并且存储在void*类型的第二个指针中的指针没有从堆中删除并释放。在该类的std::map中调用的void ShutDown(void);的{​​{1}}方法的class Engine中进行迭代。

我将发布代码并从执行中输出。

引擎头文件:

destructor

引擎源文件:

#ifndef _TEST_ENGINE_H_
#define _TEST_ENGINE_H_

#include "test_graphics_system.h"

#include <iostream>
#include <map>

namespace Core {
    enum class EngineStatus {
        Invalid,

        Constructing,
        Setup,

        Running,

        ShutDown,
        Destroying
    };

    class Engine
    {
    public:
        Engine(void);
        ~Engine(void);

        template<class T> T * GetSystem(SystemType systemType)
        {
            if (mSystems[systemType])
            {
                return (T*)mSystems[systemType];
            }
            else
            {
                std::wcout << "System doe not exist" << std::endl;
            }
            return nullptr;
        }

        int Run(void);

    private:
        template<class T> void AddSystem(T * system)
        {
            size_t count = mSystems.size();
            auto pair = std::make_pair(system->GetType(), (T*)system);
            mSystems.insert(pair);

            if (count == mSystems.size())
                std::wcout << "System failed to be added" << std::endl;
            else
                std::wcout << "System added" << std::endl;
        }

        void Setup(void);
        void ShutDown(void);

        void SetupGraphicsSystem(void);

        static EngineStatus mEngineStatus;

        std::map<SystemType, void*> mSystems;

        bool mRunning;
    };
}

#endif _TEST_ENGINE_H_

主要源文件:

#include "test_engine.h"

using namespace std;
using namespace Core;

EngineStatus Engine::mEngineStatus = EngineStatus::Invalid;

Engine::Engine(void)
{
    mEngineStatus = EngineStatus::Constructing;

    Setup();
}

Engine::~Engine(void)
{
    mEngineStatus = EngineStatus::Destroying;

    ShutDown();
}

int Engine::Run(void)
{
    mEngineStatus = EngineStatus::Running;

    return 0;
}

void Engine::Setup(void)
{
    mEngineStatus = EngineStatus::Setup;
    SetupGraphicsSystem();
}

void Engine::ShutDown(void)
{
    mEngineStatus = EngineStatus::ShutDown;

    wcout << endl;
    int count = 0;
    size_t total = mSystems.size();
    for (auto obj : mSystems)
    {
        safe_delete(obj.second);
        wcout << "\rSystem(s) deleted: " << ++count << " of " << total;
    }
}

void Engine::SetupGraphicsSystem(void)
{
    GraphicsSystem * gs = new GraphicsSystem(mSystems.size(), L"GraphicsSystem01", SystemType::Graphics);
    AddSystem(gs);
}

上次运行时的输出:

#include "safe_del_rel.h"
#include "strings.h"

#include "test_engine.h"

using namespace std;
using namespace Core;

void _DebugMemLeakDetection(void) {
#if defined(_DEBUG) || defined(DEBUG)
    int flag = _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    flag |= _CRTDBG_LEAK_CHECK_DF; // Turn on leak-checking bit
    _CrtSetDbgFlag(flag);
    _CrtSetBreakAlloc(0);
#endif
}

int main(int argv, char argc[])
{
    _DebugMemLeakDetection();

    Engine * eng = new Engine();
    eng->Run();

    system("pause");
    safe_delete(eng);
    return 0;
}

如果有人可以帮助胸膜炎。

1 个答案:

答案 0 :(得分:2)

删除void *指针会导致不确定的行为,大多数编译器都会对此发出警告。 GraphicsSystem的存储将被释放时,其析构函数将不会被调用。

通常在C ++中,您会声明std::map<SystemType, Base*> mSystems;,其中Base是您的所有系统派生的某个类,尽管映射到指向Base的智能指针几乎总是一个更好的主意。如果这是不可能的(例如GraphicsSystem是外部类),则可以例如将其包装在从Base派生的模板句柄中。