我将在下面链接这些类和执行的输出。
问题是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;
}
如果有人可以帮助胸膜炎。
答案 0 :(得分:2)
删除void *
指针会导致不确定的行为,大多数编译器都会对此发出警告。 GraphicsSystem
的存储将被释放时,其析构函数将不会被调用。
通常在C ++中,您会声明std::map<SystemType, Base*> mSystems;
,其中Base
是您的所有系统派生的某个类,尽管映射到指向Base
的智能指针几乎总是一个更好的主意。如果这是不可能的(例如GraphicsSystem
是外部类),则可以例如将其包装在从Base
派生的模板句柄中。