Skip to content

Commit ef2f63a

Browse files
authored
Merge pull request godotengine#1260 from Klaim/master
Fixes crash in ClassDB::deinitialize due to usage of invalid iterator.
2 parents cd61a9b + 5134c82 commit ef2f63a

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

src/core/class_db.cpp

+12-3
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ void ClassDB::initialize(GDExtensionInitializationLevel p_level) {
352352
}
353353

354354
void ClassDB::deinitialize(GDExtensionInitializationLevel p_level) {
355+
std::set<StringName> to_erase;
355356
for (std::vector<StringName>::reverse_iterator i = class_register_order.rbegin(); i != class_register_order.rend(); ++i) {
356357
const StringName &name = *i;
357358
const ClassInfo &cl = classes[name];
@@ -362,12 +363,20 @@ void ClassDB::deinitialize(GDExtensionInitializationLevel p_level) {
362363

363364
internal::gdextension_interface_classdb_unregister_extension_class(internal::library, name._native_ptr());
364365

365-
for (auto method : cl.method_map) {
366+
for (const std::pair<const StringName, MethodBind *> &method : cl.method_map) {
366367
memdelete(method.second);
367368
}
368369

369-
classes.erase(*i);
370-
class_register_order.erase((i + 1).base());
370+
classes.erase(name);
371+
to_erase.insert(name);
372+
}
373+
374+
{
375+
// The following is equivalent to c++20 `std::erase_if(class_register_order, [&](const StringName& name){ return to_erase.contains(name); });`
376+
std::vector<StringName>::iterator it = std::remove_if(class_register_order.begin(), class_register_order.end(), [&](const StringName &p_name) {
377+
return to_erase.count(p_name) > 0;
378+
});
379+
class_register_order.erase(it, class_register_order.end());
371380
}
372381
}
373382

0 commit comments

Comments
 (0)