From c6d5864aa956c8596d346654ef09baee607a7731 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Tue, 2 Mar 2021 12:39:04 -0500 Subject: [PATCH] Port SpawnGroup stuff to unique_ptr to fix leak This was leaking on #repop, unsure of other cases, smart pointers should cover us though. Direct leak of 3600 byte(s) in 18 object(s) allocated from: #0 0x7f2b3dbe0d30 in operator new(unsigned long) (/lib/x86_64-linux-gnu/libasan.so.5+0xead30) #1 0x5645dc7c9dff in ZoneDatabase::LoadSpawnGroups(char const*, unsigned short, SpawnGroupList*) ../zone/spawngroup.cpp:241 #2 0x5645dc9db3f5 in Zone::Depop(bool) ../zone/zone.cpp:1746 #3 0x5645dca1ba6b in Zone::Repop(unsigned int) ../zone/zone.cpp:1777 #4 0x5645db4624b7 in command_repop(Client*, Seperator const*) ../zone/command.cpp:5683 Indirect leak of 6552 byte(s) in 273 object(s) allocated from: #0 0x7f26f2ff8d30 in operator new(unsigned long) (/lib/x86_64-linux-gnu/libasan.so.5+0xead30) #1 0x558d00490bc6 in __gnu_cxx::new_allocator >::allocate(unsigned long, void const*) /usr/include/c++/8/ext/new_allocator.h:111 #2 0x558d00490bc6 in std::allocator_traits > >::allocate(std::allocator >&, unsigned long) /usr/include/c++/8/bits/alloc_traits.h:436 #3 0x558d00490bc6 in std::__cxx11::_List_base >::_M_get_node() /usr/include/c++/8/bits/stl_list.h:450 #4 0x558d00490bc6 in std::_List_node* std::__cxx11::list >::_M_create_node(SpawnEntry* const&) /usr/include/c++/8/bits/stl_list.h:642 #5 0x558d00490bc6 in void std::__cxx11::list >::_M_insert(std::_List_iterator, SpawnEntry* const&) /usr/include/c++/8/bits/stl_list.h:1903 #6 0x558d00490bc6 in std::__cxx11::list >::push_back(SpawnEntry* const&) /usr/include/c++/8/bits/stl_list.h:1220 #7 0x558d00490bc6 in SpawnGroup::AddSpawnEntry(SpawnEntry*) ../zone/spawngroup.cpp:122 #8 0x558d00490bc6 in ZoneDatabase::LoadSpawnGroups(char const*, unsigned short, SpawnGroupList*) ../zone/spawngroup.cpp:291 #9 0x558d006a1465 in Zone::Depop(bool) ../zone/zone.cpp:1746 #10 0x558d006e1adb in Zone::Repop(unsigned int) ../zone/zone.cpp:1777 --- zone/spawngroup.cpp | 49 +++++++++++++-------------------------------- zone/spawngroup.h | 10 ++++----- 2 files changed, 19 insertions(+), 40 deletions(-) diff --git a/zone/spawngroup.cpp b/zone/spawngroup.cpp index 97f3dab9a..4321a41b5 100644 --- a/zone/spawngroup.cpp +++ b/zone/spawngroup.cpp @@ -78,12 +78,9 @@ uint32 SpawnGroup::GetNPCType(uint16 in_filter) return (0); } - std::list::iterator cur, end; - std::list possible; - cur = list_.begin(); - end = list_.end(); - for (; cur != end; ++cur) { - SpawnEntry *se = *cur; + std::list possible; + for (auto &it : list_) { + auto se = it.get(); if (!entity_list.LimitCheckType(se->NPCType, se->npc_spawn_limit)) { continue; @@ -95,6 +92,7 @@ uint32 SpawnGroup::GetNPCType(uint16 in_filter) totalchance += se->chance; possible.push_back(se); } + if (totalchance == 0) { return 0; } @@ -102,10 +100,7 @@ uint32 SpawnGroup::GetNPCType(uint16 in_filter) int32 roll = 0; roll = zone->random.Int(0, totalchance - 1); - cur = possible.begin(); - end = possible.end(); - for (; cur != end; ++cur) { - SpawnEntry *se = *cur; + for (auto se : possible) { if (roll < se->chance) { npcType = se->NPCType; break; @@ -117,42 +112,28 @@ uint32 SpawnGroup::GetNPCType(uint16 in_filter) return npcType; } -void SpawnGroup::AddSpawnEntry(SpawnEntry *newEntry) +void SpawnGroup::AddSpawnEntry(std::unique_ptr &newEntry) { - list_.push_back(newEntry); + list_.push_back(std::move(newEntry)); } SpawnGroup::~SpawnGroup() { - std::list::iterator cur, end; - cur = list_.begin(); - end = list_.end(); - for (; cur != end; ++cur) { - SpawnEntry *tmp = *cur; - safe_delete(tmp); - } list_.clear(); } SpawnGroupList::~SpawnGroupList() { - std::map::iterator cur, end; - cur = m_spawn_groups.begin(); - end = m_spawn_groups.end(); - for (; cur != end; ++cur) { - SpawnGroup *tmp = cur->second; - safe_delete(tmp); - } m_spawn_groups.clear(); } -void SpawnGroupList::AddSpawnGroup(SpawnGroup *new_group) +void SpawnGroupList::AddSpawnGroup(std::unique_ptr &new_group) { if (new_group == nullptr) { return; } - m_spawn_groups[new_group->id] = new_group; + m_spawn_groups[new_group->id] = std::move(new_group); } SpawnGroup *SpawnGroupList::GetSpawnGroup(uint32 in_id) @@ -161,7 +142,7 @@ SpawnGroup *SpawnGroupList::GetSpawnGroup(uint32 in_id) return nullptr; } - return (m_spawn_groups[in_id]); + return (m_spawn_groups[in_id].get()); } bool SpawnGroupList::RemoveSpawnGroup(uint32 in_id) @@ -224,7 +205,7 @@ bool ZoneDatabase::LoadSpawnGroups(const char *zone_name, uint16 version, SpawnG } for (auto row = results.begin(); row != results.end(); ++row) { - auto new_spawn_group = new SpawnGroup( + auto new_spawn_group = std::make_unique( atoi(row[0]), row[1], atoi(row[2]), @@ -272,7 +253,7 @@ bool ZoneDatabase::LoadSpawnGroups(const char *zone_name, uint16 version, SpawnG } for (auto row = results.begin(); row != results.end(); ++row) { - auto new_spawn_entry = new SpawnEntry( + auto new_spawn_entry = std::make_unique( atoi(row[1]), atoi(row[2]), atoi(row[3]), @@ -282,7 +263,6 @@ bool ZoneDatabase::LoadSpawnGroups(const char *zone_name, uint16 version, SpawnG SpawnGroup *spawn_group = spawn_group_list->GetSpawnGroup(atoi(row[0])); if (!spawn_group) { - safe_delete(new_spawn_entry); continue; } @@ -337,7 +317,7 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList *spawn row[3] ); - auto new_spawn_group = new SpawnGroup( + auto new_spawn_group = std::make_unique( atoi(row[0]), row[1], atoi(row[2]), @@ -380,7 +360,7 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList *spawn } for (auto row = results.begin(); row != results.end(); ++row) { - auto new_spawn_entry = new SpawnEntry( + auto new_spawn_entry = std::make_unique( atoi(row[1]), atoi(row[2]), atoi(row[3]), @@ -398,7 +378,6 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList *spawn SpawnGroup *spawn_group = spawn_group_list->GetSpawnGroup(atoi(row[0])); if (!spawn_group) { - safe_delete(new_spawn_entry); continue; } diff --git a/zone/spawngroup.h b/zone/spawngroup.h index a1068cea0..20b84b734 100644 --- a/zone/spawngroup.h +++ b/zone/spawngroup.h @@ -22,6 +22,7 @@ #include #include +#include class SpawnEntry { public: @@ -55,7 +56,7 @@ public: ~SpawnGroup(); uint32 GetNPCType(uint16 condition_value_filter=1); - void AddSpawnEntry(SpawnEntry *newEntry); + void AddSpawnEntry(std::unique_ptr &newEntry); uint32 id; bool wp_spawns; // if true, spawn NPCs at a random waypoint location (if spawnpoint has a grid) instead of the spawnpoint's loc float roamdist; @@ -66,7 +67,7 @@ public: uint32 despawn_timer; private: char name_[120]; - std::list list_; + std::list> list_; uint8 group_spawn_limit; //max # of this entry which can be spawned by this group }; @@ -75,14 +76,13 @@ public: SpawnGroupList() {} ~SpawnGroupList(); - void AddSpawnGroup(SpawnGroup *new_group); + void AddSpawnGroup(std::unique_ptr &new_group); SpawnGroup *GetSpawnGroup(uint32 id); bool RemoveSpawnGroup(uint32 in_id); void ClearSpawnGroups(); void ReloadSpawnGroups(); private: - //LinkedList list_; - std::map m_spawn_groups; + std::map> m_spawn_groups; }; #endif