1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-29 23:07:48 +02:00

Use unique_ptr instead of raw pointers to attempt to fix crash on free

This commit is contained in:
Ivan Savenko
2023-12-16 13:42:12 +02:00
parent 5f4608c9f0
commit 1acab80fdc
2 changed files with 19 additions and 23 deletions

View File

@@ -97,11 +97,7 @@ CObjectClassesHandler::CObjectClassesHandler()
#undef SET_HANDLER #undef SET_HANDLER
} }
CObjectClassesHandler::~CObjectClassesHandler() CObjectClassesHandler::~CObjectClassesHandler() = default;
{
for(auto * p : objects)
delete p;
}
std::vector<JsonNode> CObjectClassesHandler::loadLegacyData() std::vector<JsonNode> CObjectClassesHandler::loadLegacyData()
{ {
@@ -240,9 +236,9 @@ std::string ObjectClass::getNameTranslated() const
return VLC->generaltexth->translate(getNameTextID()); return VLC->generaltexth->translate(getNameTextID());
} }
ObjectClass * CObjectClassesHandler::loadFromJson(const std::string & scope, const JsonNode & json, const std::string & name, size_t index) std::unique_ptr<ObjectClass> CObjectClassesHandler::loadFromJson(const std::string & scope, const JsonNode & json, const std::string & name, size_t index)
{ {
auto * obj = new ObjectClass(); auto obj = std::make_unique<ObjectClass>();
obj->modScope = scope; obj->modScope = scope;
obj->identifier = name; obj->identifier = name;
@@ -263,31 +259,31 @@ ObjectClass * CObjectClassesHandler::loadFromJson(const std::string & scope, con
if ( subMeta != "core") if ( subMeta != "core")
logMod->warn("Object %s:%s.%s - attempt to load object with preset index! This option is reserved for built-in mod", subMeta, name, subData.first ); logMod->warn("Object %s:%s.%s - attempt to load object with preset index! This option is reserved for built-in mod", subMeta, name, subData.first );
size_t subIndex = subData.second["index"].Integer(); size_t subIndex = subData.second["index"].Integer();
loadSubObject(subData.second.meta, subData.first, subData.second, obj, subIndex); loadSubObject(subData.second.meta, subData.first, subData.second, obj.get(), subIndex);
} }
else else
loadSubObject(subData.second.meta, subData.first, subData.second, obj); loadSubObject(subData.second.meta, subData.first, subData.second, obj.get());
} }
if (obj->id == MapObjectID::MONOLITH_TWO_WAY) if (obj->id == MapObjectID::MONOLITH_TWO_WAY)
generateExtraMonolithsForRMG(obj); generateExtraMonolithsForRMG(obj.get());
return obj; return obj;
} }
void CObjectClassesHandler::loadObject(std::string scope, std::string name, const JsonNode & data) void CObjectClassesHandler::loadObject(std::string scope, std::string name, const JsonNode & data)
{ {
auto * object = loadFromJson(scope, data, name, objects.size()); objects.push_back(loadFromJson(scope, data, name, objects.size()));
objects.push_back(object);
VLC->identifiersHandler->registerObject(scope, "object", name, object->id); VLC->identifiersHandler->registerObject(scope, "object", name, objects.back()->id);
} }
void CObjectClassesHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) void CObjectClassesHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index)
{ {
auto * object = loadFromJson(scope, data, name, index); assert(objects[index] == nullptr); // ensure that this id was not loaded before
assert(objects[(si32)index] == nullptr); // ensure that this id was not loaded before
objects[static_cast<si32>(index)] = object; objects[index] = loadFromJson(scope, data, name, index);
VLC->identifiersHandler->registerObject(scope, "object", name, object->id); VLC->identifiersHandler->registerObject(scope, "object", name, objects[index]->id);
} }
void CObjectClassesHandler::loadSubObject(const std::string & identifier, JsonNode config, MapObjectID ID, MapObjectSubID subID) void CObjectClassesHandler::loadSubObject(const std::string & identifier, JsonNode config, MapObjectID ID, MapObjectSubID subID)
@@ -299,7 +295,7 @@ void CObjectClassesHandler::loadSubObject(const std::string & identifier, JsonNo
objects[ID.getNum()]->objects.resize(subID.getNum()+1); objects[ID.getNum()]->objects.resize(subID.getNum()+1);
JsonUtils::inherit(config, objects.at(ID.getNum())->base); JsonUtils::inherit(config, objects.at(ID.getNum())->base);
loadSubObject(config.meta, identifier, config, objects[ID.getNum()], subID.getNum()); loadSubObject(config.meta, identifier, config, objects[ID.getNum()].get(), subID.getNum());
} }
void CObjectClassesHandler::removeSubObject(MapObjectID ID, MapObjectSubID subID) void CObjectClassesHandler::removeSubObject(MapObjectID ID, MapObjectSubID subID)
@@ -335,7 +331,7 @@ TObjectTypeHandler CObjectClassesHandler::getHandlerFor(const std::string & scop
std::optional<si32> id = VLC->identifiers()->getIdentifier(scope, "object", type); std::optional<si32> id = VLC->identifiers()->getIdentifier(scope, "object", type);
if(id) if(id)
{ {
auto * object = objects[id.value()]; const auto & object = objects[id.value()];
std::optional<si32> subID = VLC->identifiers()->getIdentifier(scope, object->getJsonKey(), subtype); std::optional<si32> subID = VLC->identifiers()->getIdentifier(scope, object->getJsonKey(), subtype);
if (subID) if (subID)
@@ -356,7 +352,7 @@ std::set<MapObjectID> CObjectClassesHandler::knownObjects() const
{ {
std::set<MapObjectID> ret; std::set<MapObjectID> ret;
for(auto * entry : objects) for(auto & entry : objects)
if (entry) if (entry)
ret.insert(entry->id); ret.insert(entry->id);
@@ -406,7 +402,7 @@ void CObjectClassesHandler::beforeValidate(JsonNode & object)
void CObjectClassesHandler::afterLoadFinalization() void CObjectClassesHandler::afterLoadFinalization()
{ {
for(auto * entry : objects) for(auto & entry : objects)
{ {
if (!entry) if (!entry)
continue; continue;

View File

@@ -68,7 +68,7 @@ public:
class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase
{ {
/// list of object handlers, each of them handles only one type /// list of object handlers, each of them handles only one type
std::vector<ObjectClass * > objects; std::vector< std::unique_ptr<ObjectClass> > objects;
/// map that is filled during contruction with all known handlers. Not serializeable due to usage of std::function /// map that is filled during contruction with all known handlers. Not serializeable due to usage of std::function
std::map<std::string, std::function<TObjectTypeHandler()> > handlerConstructors; std::map<std::string, std::function<TObjectTypeHandler()> > handlerConstructors;
@@ -82,7 +82,7 @@ class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase
void loadSubObject(const std::string & scope, const std::string & identifier, const JsonNode & entry, ObjectClass * obj); void loadSubObject(const std::string & scope, const std::string & identifier, const JsonNode & entry, ObjectClass * obj);
void loadSubObject(const std::string & scope, const std::string & identifier, const JsonNode & entry, ObjectClass * obj, size_t index); void loadSubObject(const std::string & scope, const std::string & identifier, const JsonNode & entry, ObjectClass * obj, size_t index);
ObjectClass * loadFromJson(const std::string & scope, const JsonNode & json, const std::string & name, size_t index); std::unique_ptr<ObjectClass> loadFromJson(const std::string & scope, const JsonNode & json, const std::string & name, size_t index);
void generateExtraMonolithsForRMG(ObjectClass * container); void generateExtraMonolithsForRMG(ObjectClass * container);