Fix memory leaks (#668)
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s

This commit is contained in:
smallmodel 2025-02-18 23:27:43 +01:00 committed by GitHub
commit ad1748b8be
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 142 additions and 67 deletions

View file

@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@ -26,9 +26,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "playerbot.h"
#include "g_bot.h"
static saved_bot_t *saved_bots = NULL;
static unsigned int num_saved_bots = 0;
static unsigned int botId = 0;
static saved_bot_t *saved_bots = NULL;
static unsigned int num_saved_bots = 0;
static unsigned int botId = 0;
Container<str> alliedModelList;
Container<str> germanModelList;
@ -387,7 +387,7 @@ bool G_IsPlayer(gentity_t *ent)
G_GetRandomAlliedPlayerModel
============
*/
const char* G_GetRandomAlliedPlayerModel()
const char *G_GetRandomAlliedPlayerModel()
{
if (!alliedModelList.NumObjects()) {
return "";
@ -402,7 +402,7 @@ const char* G_GetRandomAlliedPlayerModel()
G_GetRandomGermanPlayerModel
============
*/
const char* G_GetRandomGermanPlayerModel()
const char *G_GetRandomGermanPlayerModel()
{
if (!germanModelList.NumObjects()) {
return "";
@ -580,8 +580,8 @@ void G_SaveBots()
saved_bots = NULL;
}
const BotControllerManager& manager = botManager.getControllerManager();
unsigned int numSpawnedBots = manager.getControllers().NumObjects();
const BotControllerManager& manager = botManager.getControllerManager();
unsigned int numSpawnedBots = manager.getControllers().NumObjects();
if (!numSpawnedBots) {
return;
@ -590,7 +590,6 @@ void G_SaveBots()
saved_bots = new saved_bot_t[numSpawnedBots];
num_saved_bots = 0;
count = manager.getControllers().NumObjects();
assert(count <= numSpawnedBots);
@ -686,6 +685,18 @@ int G_CountClients()
return count;
}
/*
===========
G_RestartBots
Save bots
============
*/
void G_RestartBots()
{
G_SaveBots();
}
/*
===========
G_ResetBots
@ -695,8 +706,6 @@ Save and reset the bot count
*/
void G_ResetBots()
{
G_SaveBots();
botManager.Cleanup();
botId = 0;

View file

@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@ -26,20 +26,21 @@ struct saved_bot_t {
char userinfo[MAX_INFO_STRING];
};
void G_BotBegin(gentity_t *ent);
void G_BotThink(gentity_t *ent, int msec);
void G_BotShift(int clientNum);
gentity_t *G_GetFirstBot();
void G_AddBot(const saved_bot_t *saved = NULL);
void G_AddBots(unsigned int num);
void G_RemoveBot(gentity_t *ent);
void G_RemoveBots(unsigned int num);
bool G_IsBot(gentity_t *ent);
bool G_IsPlayer(gentity_t *ent);
void G_ResetBots();
void G_BotInit();
void G_BotFrame();
void G_BotPostInit();
void G_SpawnBots();
const char* G_GetRandomAlliedPlayerModel();
const char* G_GetRandomGermanPlayerModel();
void G_BotBegin(gentity_t *ent);
void G_BotThink(gentity_t *ent, int msec);
void G_BotShift(int clientNum);
gentity_t *G_GetFirstBot();
void G_AddBot(const saved_bot_t *saved = NULL);
void G_AddBots(unsigned int num);
void G_RemoveBot(gentity_t *ent);
void G_RemoveBots(unsigned int num);
bool G_IsBot(gentity_t *ent);
bool G_IsPlayer(gentity_t *ent);
void G_ResetBots();
void G_RestartBots();
void G_BotInit();
void G_BotFrame();
void G_BotPostInit();
void G_SpawnBots();
const char *G_GetRandomAlliedPlayerModel();
const char *G_GetRandomGermanPlayerModel();

View file

@ -227,9 +227,13 @@ void G_AllocGameData(void)
void G_DeAllocGameData(void)
{
// Initialize debug lines
// Free up debug lines
G_DeAllocDebugLines();
// Added in OPM
// Free up debug strings
G_DeAllocDebugStrings();
// free up the entities
if (g_entities) {
gi.Free(g_entities);
@ -914,6 +918,9 @@ void G_Restart(void)
// Added in 2.0
G_ResetSmokeSprites();
// Added in OPM
G_RestartBots();
}
void G_SetFrameNumber(int framenum)

View file

@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@ -686,10 +686,17 @@ void GameScript::ArchiveCodePos(Archiver& arc, unsigned char **codePos)
void GameScript::Close(void)
{
// Free up catch blocks
for (int i = m_CatchBlocks.NumObjects(); i > 0; i--) {
delete m_CatchBlocks.ObjectAt(i);
}
// Added in OPM
// Free up allocated state scripts
for (int i = m_StateScripts.NumObjects(); i > 0; i--) {
delete m_StateScripts.ObjectAt(i);
}
m_CatchBlocks.FreeObjectList();
if (m_ProgToSource) {
@ -814,7 +821,11 @@ StateScript *GameScript::CreateCatchStateScript(unsigned char *try_begin_code_po
StateScript *GameScript::CreateSwitchStateScript(void)
{
return new StateScript;
StateScript *stateScript = new StateScript;
m_StateScripts.AddObject(stateScript);
return stateScript;
}
StateScript *GameScript::GetCatchStateScript(unsigned char *in, unsigned char *& out)
@ -927,7 +938,8 @@ void ScriptThreadLabel::Execute(Listener *listener, Event *ev) const
Execute(listener, *ev);
}
void ScriptThreadLabel::Execute(Listener *pSelf, const SafePtr<Listener>& listener, const SafePtr<Listener>& param) const
void ScriptThreadLabel::Execute(Listener *pSelf, const SafePtr<Listener>& listener, const SafePtr<Listener>& param)
const
{
if (!m_Script) {
return;

View file

@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@ -118,7 +118,8 @@ class GameScript : public AbstractScript
{
protected:
// try/throw variable
Container<CatchBlock *> m_CatchBlocks;
Container<CatchBlock *> m_CatchBlocks;
Container<StateScript *> m_StateScripts;
public:
// program variables

View file

@ -70,6 +70,11 @@ void Alias_ListClear(AliasList_t *list)
}
for (node = list->data_list; node != NULL; node = next) {
if (node->subtitle) {
// Added in OPM
Z_Free(node->subtitle);
}
next = node->next;
Z_Free(node);
}

View file

@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@ -57,6 +57,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#endif
ClassDef *ClassDef::classlist;
ClassDef *ClassDef::classroot;
int ClassDef::numclasses;
int ClassDef::dump_numclasses;
@ -78,7 +79,7 @@ void ClassDef::SortClassList(Container<ClassDef *> *sortedList)
sortedList->Resize(numclasses);
for (c = classlist->next; c != classlist; c = c->next) {
for (c = classlist; c; c = c->next) {
sortedList->AddObject(c);
}
@ -92,7 +93,7 @@ ClassDef *getClassForID(const char *name)
ClassDef *classlist = ClassDef::classlist;
ClassDef *c;
for (c = classlist->next; c != classlist; c = c->next) {
for (c = classlist; c; c = c->next) {
if (c->classID && !Q_stricmp(c->classID, name)) {
return c;
}
@ -110,7 +111,7 @@ ClassDef *getClass(const char *name)
ClassDef *list = ClassDef::classlist;
ClassDef *c;
for (c = list->next; c != list; c = c->next) {
for (c = list; c; c = c->next) {
if (Q_stricmp(c->classname, name) == 0) {
return c;
}
@ -129,7 +130,7 @@ void listAllClasses(void)
ClassDef *c;
ClassDef *list = ClassDef::classlist;
for (c = list->next; c != list; c = c->next) {
for (c = list; c; c = c->next) {
CLASS_DPrintf("%s\n", c->classname);
}
}
@ -353,7 +354,7 @@ ClassDef::ClassDef(
ClassDef *node;
if (classlist == NULL) {
classlist = new ClassDef;
classlist = this;
}
this->classname = classname;
@ -374,7 +375,7 @@ ClassDef::ClassDef(
this->classID = "";
}
for (node = classlist->next; node != classlist; node = node->next) {
for (node = classlist; node; node = node->next) {
if ((node->super == NULL) && (!Q_stricmp(node->superclass, this->classname))
&& (Q_stricmp(node->classname, "Class"))) {
node->super = this;
@ -382,7 +383,7 @@ ClassDef::ClassDef(
}
// Add to front of list
LL_AddFirst(classlist, this, prev, next);
LL_SafeAdd(classroot, this, next, prev);
numclasses++;
}
@ -391,24 +392,24 @@ ClassDef::~ClassDef()
{
ClassDef *node;
if (classlist != this) {
LL_Remove(this, prev, next);
LL_SafeRemoveRoot(classlist, this, next, prev);
// Check if any subclasses were initialized before their superclass
for (node = classlist->next; node != classlist; node = node->next) {
if (node->super == this) {
node->super = NULL;
}
// Check if any subclasses were initialized before their superclass
for (node = classlist; node; node = node->next) {
if (node->super == this) {
node->super = NULL;
}
} else {
// If the head of the list is deleted before the list is cleared, then we may have problems
assert(this->next == this->prev);
}
if (responseLookup) {
delete[] responseLookup;
responseLookup = NULL;
}
#ifdef WITH_SCRIPT_ENGINE
if (waitTillSet) {
delete waitTillSet;
}
#endif
}
#ifdef WITH_SCRIPT_ENGINE
@ -497,7 +498,7 @@ void ClassDef::BuildResponseList(void)
}
//size will be total event count, because it WAS faster to look for an event via eventnum
//nowadays there's not much overhead in performance, TODO: change size to appropriate.
num = Event::NumEventCommands();
num = Event::NumEventCommands();
responseLookup = (ResponseDef<Class> **)new char[sizeof(ResponseDef<Class> *) * num];
memset(responseLookup, 0, sizeof(ResponseDef<Class> *) * num);
@ -539,7 +540,7 @@ void ClassDef::BuildEventResponses(void)
amount = 0;
numclasses = 0;
for (c = classlist->next; c != classlist; c = c->next) {
for (c = classlist; c; c = c->next) {
c->BuildResponseList();
amount += c->numEvents * sizeof(Response *);
@ -692,7 +693,13 @@ void DumpClass(FILE *class_file, const char *className)
CLASS_Print(class_file, "\n");
if (classDef->classID[0]) {
CLASS_Print(class_file, "<h2> <a name=\"%s\">%s (<i>%s</i>)</a>", classDef->classname, classDef->classname, classDef->classID);
CLASS_Print(
class_file,
"<h2> <a name=\"%s\">%s (<i>%s</i>)</a>",
classDef->classname,
classDef->classname,
classDef->classID
);
} else {
CLASS_Print(class_file, "<h2> <a name=\"%s\">%s</a>", classDef->classname, classDef->classname);
}

View file

@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2023 the OpenMoHAA team
Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@ -87,15 +87,19 @@ class Event;
} \
bool classname::WaitTillAllowed(str s) \
{ \
for(ClassDef* c = classinfo(); c; c = c->super) { \
if (c->WaitTillDefined(s)) { return true; } \
for (ClassDef *c = classinfo(); c; c = c->super) { \
if (c->WaitTillDefined(s)) { \
return true; \
} \
} \
return false; \
} \
bool classname::WaitTillAllowed(const_str s) \
{ \
for(ClassDef* c = classinfo(); c; c = c->super) { \
if (c->WaitTillDefined(s)) { return true; } \
for (ClassDef *c = classinfo(); c; c = c->super) { \
if (c->WaitTillDefined(s)) { \
return true; \
} \
} \
return false; \
} \
@ -188,6 +192,7 @@ public:
int numEvents;
static ClassDef *classlist;
static ClassDef *classroot;
static int numclasses;
static int dump_numclasses;

View file

@ -526,3 +526,18 @@ void Container<Type>::Copy(const Container<Type>& container)
return;
}
template<typename T>
void *operator new(size_t count, Container<T>& container)
{
(void)count;
assert(count == sizeof(T));
return &container.ObjectAt(container.AddObject());
}
template<typename T>
void operator delete(void *ptr, Container<T>& container)
{
container.RemoveObject((T *)ptr);
}

View file

@ -26,14 +26,27 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "q_shared.h"
class LightClass {
class LightClass
{
public:
#ifndef _DEBUG_MEM
void* operator new(size_t);
void operator delete(void*);
void *operator new(size_t);
void operator delete(void *);
void* operator new(size_t size, void* placement);
void operator delete(void* ptr, void* placement);
void *operator new(size_t size, void *placement);
void operator delete(void *ptr, void *placement);
template<typename T>
void *operator new(size_t size, T& placement)
{
return operator new(size, (void *)&placement);
}
template<typename T>
void operator delete(void *ptr, T& placement)
{
return operator delete(ptr, (void *)&placement);
}
#endif
};

View file

@ -408,7 +408,7 @@ public:
#define NODE_CANCEL 1
#define NODE_FIXED_EVENT 2
class EventQueueNode
class EventQueueNode : public LightClass
{
public:
Event *event;