c ++ std :: map删除指针[关闭]

问题描述 投票:-3回答:1

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

问题是,std::map正在迭代,存储在第二个类型为void*的指针不会从堆中删除并释放。 std::mapvoid ShutDown(void);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;
}

上次运行时的输出:

'test_engine_console.exe' (Win32): Loaded 'C:\vs_projects\test_engine\x64\Debug\test_engine_console.exe'. Symbols loaded.
'test_engine_console.exe' (Win32): Loaded 'C:\Windows\System32\ntdll.dll'. Cannot find or open the PDB file.
'test_engine_console.exe' (Win32): Loaded 'C:\Windows\System32\kernel32.dll'. Cannot find or open the PDB file.
'test_engine_console.exe' (Win32): Loaded 'C:\Windows\System32\KernelBase.dll'. Cannot find or open the PDB file.
'test_engine_console.exe' (Win32): Loaded 'C:\Windows\System32\msvcp140d.dll'. Cannot find or open the PDB file.
'test_engine_console.exe' (Win32): Loaded 'C:\Windows\System32\ucrtbased.dll'. Cannot find or open the PDB file.
'test_engine_console.exe' (Win32): Loaded 'C:\Windows\System32\vcruntime140d.dll'. Cannot find or open the PDB file.
'test_engine_console.exe' (Win32): Loaded 'C:\Windows\System32\vcruntime140d.dll'. Cannot find or open the PDB file.
'test_engine_console.exe' (Win32): Unloaded 'C:\Windows\System32\vcruntime140d.dll'
'test_engine_console.exe' (Win32): Loaded 'C:\Windows\System32\kernel.appcore.dll'. Cannot find or open the PDB file.
'test_engine_console.exe' (Win32): Loaded 'C:\Windows\System32\msvcrt.dll'. Cannot find or open the PDB file.
'test_engine_console.exe' (Win32): Loaded 'C:\Windows\System32\rpcrt4.dll'. Cannot find or open the PDB file.
The thread 0x4134 has exited with code 0 (0x0).
The thread 0x46ac has exited with code 0 (0x0).
The thread 0x307c has exited with code 0 (0x0).
Detected memory leaks!
Dumping objects ->
{161} normal block at 0x00000293DD5E2680, 48 bytes long.
 Data: <G r a p h i c s > 47 00 72 00 61 00 70 00 68 00 69 00 63 00 73 00 
{160} normal block at 0x00000293DD5E1820, 16 bytes long.
 Data: < R]             > A0 52 5D DD 93 02 00 00 00 00 00 00 00 00 00 00 
Object dump complete.
The program '[12764] test_engine_console.exe' has exited with code 0 (0x0).

如果有人可以帮助plesae做。

c++ dictionary std free
1个回答
2
投票

删除void *指针会导致未定义的行为,大多数编译器会发出警告。虽然将释放GraphicsSystem的存储空间,但不会调用其析构函数。

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

© www.soinside.com 2019 - 2024. All rights reserved.