我将链接下面的执行类和输出。
问题是,std::map
正在迭代,存储在第二个类型为void*
的指针不会从堆中删除并释放。 std::map
在void 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做。
删除void *
指针会导致未定义的行为,大多数编译器会发出警告。虽然将释放GraphicsSystem
的存储空间,但不会调用其析构函数。
通常在C ++中你会声明std::map<SystemType, Base*> mSystems;
,其中Base
是你所有系统派生的类,尽管映射到Base
的智能指针几乎总是一个更好的主意。如果这是不可能的(例如GraphicsSystem
是一个外部类),那么你可以将它包装在一个衍生自Base
的模板化句柄中。