Alright so I've been struggling to find the error but I simply can't. Given the following code:
#include <iostream>
#include <vector>
enum ScriptType
{
SCRIPT_TYPE_CREATURE_SCRIPT,
SCRIPT_TYPE_PLAYER_SCRIPT
};
class Script
{
private:
ScriptType type;
public:
Script(ScriptType type) : type(type)
{
}
ScriptType getScriptType() const
{
return type;
}
};
class CreatureScript : public Script
{
public:
CreatureScript() : Script(SCRIPT_TYPE_CREATURE_SCRIPT)
{
}
virtual void OnDealDamage() { }
virtual void OnKill() { }
};
class PlayerScript : public Script
{
public:
PlayerScript() : Script(SCRIPT_TYPE_PLAYER_SCRIPT)
{
}
virtual void OnSay() { }
};
class ScriptFactory
{
private:
static std::vector<Script *> scripts;
public:
static void Register(Script *s);
static void Unregister();
static std::vector<Script *> getScriptsByType(ScriptType type);
};
std::vector<Script *> ScriptFactory::scripts;
void ScriptFactory::Register(Script *s)
{
scripts.push_back(s);
std::cout << "Pushed at address: " << s << std::endl;
}
void ScriptFactory::Unregister()
{
std::vector<Script *>::iterator iter = scripts.begin();
for (iter; iter != scripts.end(); ++iter)
{
std::cout << "Trying to free memory at: " << *iter << std::endl;
delete *iter;
}
scripts.clear();
}
std::vector<Script *> ScriptFactory::getScriptsByType(ScriptType type)
{
std::vector<Script *>::iterator iter = scripts.begin();
std::vector<Script *> values;
for (iter; iter != scripts.end(); ++iter)
if ((*iter)->getScriptType() == type)
values.push_back(*iter);
return values;
}
class CreatureScriptTest : public CreatureScript
{
public:
CreatureScriptTest() : CreatureScript()
{
}
void OnDealDamage()
{
std::cout << "OnDealDamage() called from CreatureScriptTest." << std::endl;
}
};
class CreatureScriptTest2 : public CreatureScript
{
public:
CreatureScriptTest2() : CreatureScript()
{
}
void OnDealDamage()
{
std::cout << "OnDealDamage() called from CreatureScriptTest2." << std::endl;
}
};
class PlayerScriptTest : public PlayerScript
{
public:
PlayerScriptTest() : PlayerScript()
{
}
void OnSay()
{
std::cout << "OnSay() called from PlayerScriptTest." << std::endl;
}
};
class ScriptMgr
{
typedef std::vector<Script *> ScriptStorage;
#define ITERATE(container, type) \
ScriptStorage scripts = ScriptFactory::getScriptsByType(type); \
for (ScriptStorage::iterator itr = container.begin(); itr != container.end(); ++itr)
public:
static void OnCreatureDealDamage()
{
ITERATE(scripts, SCRIPT_TYPE_CREATURE_SCRIPT)
static_cast<CreatureScript *>(*itr)->OnDealDamage();
}
static void OnCreatureKill()
{
ITERATE(scripts, SCRIPT_TYPE_CREATURE_SCRIPT)
static_cast<CreatureScript *>(*itr)->OnKill();
}
static void OnPlayerSay()
{
ITERATE(scripts, SCRIPT_TYPE_PLAYER_SCRIPT)
static_cast<PlayerScript *>(*itr)->OnSay();
}
};
int main()
{
ScriptFactory::Register(new CreatureScriptTest());
ScriptFactory::Register(new CreatureScriptTest2());
ScriptFactory::Register(new PlayerScriptTest());
ScriptMgr::OnCreatureDealDamage();
ScriptMgr::OnPlayerSay();
ScriptFactory::Unregister();
return 0;
}
It gives the correct output and everything seems to be working fine, except that I get a runtime error on ScriptFactory::Unregister() at line 71: delete *iter;
Using MSVC 2010 I get the following on running in Debug mode:
Click Here
So I see that the program is trying to free a valid memory address which was previously allocated using new. But I still get that error telling me that the pointer is invalid.