You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-19 14:31:59 +00:00
Fix leaks and crashes in OAHashMap
This changes the way the lifespan of items is managed to be consistent. Bonus: Simplify cases of destroy-then-emplace.
This commit is contained in:
@@ -35,6 +35,41 @@
|
||||
|
||||
namespace TestOAHashMap {
|
||||
|
||||
struct CountedItem {
|
||||
static int count;
|
||||
|
||||
int id;
|
||||
bool destroyed;
|
||||
|
||||
CountedItem() :
|
||||
id(-1),
|
||||
destroyed(false) {
|
||||
count++;
|
||||
}
|
||||
|
||||
CountedItem(int p_id) :
|
||||
id(p_id),
|
||||
destroyed(false) {
|
||||
count++;
|
||||
}
|
||||
|
||||
CountedItem(const CountedItem &p_other) :
|
||||
id(p_other.id),
|
||||
destroyed(false) {
|
||||
count++;
|
||||
}
|
||||
|
||||
CountedItem &operator=(const CountedItem &p_other) = default;
|
||||
|
||||
~CountedItem() {
|
||||
CRASH_COND(destroyed);
|
||||
count--;
|
||||
destroyed = true;
|
||||
}
|
||||
};
|
||||
|
||||
int CountedItem::count;
|
||||
|
||||
MainLoop *test() {
|
||||
|
||||
OS::get_singleton()->print("\n\n\nHello from test\n");
|
||||
@@ -152,6 +187,33 @@ MainLoop *test() {
|
||||
map.set(5, 1);
|
||||
}
|
||||
|
||||
// test memory management of items, should not crash or leak items
|
||||
{
|
||||
// Exercise different patterns of removal
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
{
|
||||
OAHashMap<String, CountedItem> map;
|
||||
int id = 0;
|
||||
for (int j = 0; j < 100; ++j) {
|
||||
map.insert(itos(j), CountedItem(id));
|
||||
}
|
||||
if (i <= 1) {
|
||||
for (int j = 0; j < 100; ++j) {
|
||||
map.remove(itos(j));
|
||||
}
|
||||
}
|
||||
if (i % 2 == 0) {
|
||||
map.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (CountedItem::count != 0) {
|
||||
OS::get_singleton()->print("%d != 0 (not performing the other test sub-cases, breaking...)\n", CountedItem::count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
} // namespace TestOAHashMap
|
||||
|
||||
Reference in New Issue
Block a user