[util] Fix a pile of memory leaks

Some were actually legitimate (in that they'd cause problems in a long
running game).
This commit is contained in:
Bill Currie 2023-03-05 17:04:52 +09:00
parent 9ad4f57348
commit 13f8f2b66b
8 changed files with 175 additions and 58 deletions

View file

@ -40,6 +40,7 @@
#include "QF/cbuf.h"
#include "QF/cmd.h"
#include "QF/idparse.h"
#include "QF/sys.h"
typedef struct idbuf_s {
dstring_t *buf, *line;
@ -253,3 +254,17 @@ VISIBLE cbuf_interpreter_t id_interp = {
COM_execute_sets,
NULL
};
static void
idparse_shutdown (void *data)
{
if (_com_token) {
dstring_delete (_com_token);
}
}
static void __attribute__((constructor))
idparse_init (void)
{
Sys_RegisterShutdown (idparse_shutdown, 0);
}

View file

@ -242,3 +242,16 @@ COM_ExecConfig (cbuf_t *cbuf, int skip_quakerc)
}
}
}
static void
qargs_shutdown (void *data)
{
free (largv);
free ((char *) com_cmdline);
}
static void __attribute__((constructor))
qargs_init (void)
{
Sys_RegisterShutdown (qargs_shutdown, 0);
}

View file

@ -571,6 +571,42 @@ qfs_process_path (const char *path, const char *gamedir)
}
}
static void
qfs_free_gamedir (void)
{
if (qfs_gamedir) {
if (qfs_gamedir->name)
free ((char *)qfs_gamedir->name);
if (qfs_gamedir->gamedir)
free ((char *)qfs_gamedir->gamedir);
if (qfs_gamedir->path)
free ((char *)qfs_gamedir->path);
if (qfs_gamedir->gamecode)
free ((char *)qfs_gamedir->gamecode);
if (qfs_gamedir->hudtype)
free ((char *)qfs_gamedir->hudtype);
if (qfs_gamedir->dir.def)
free ((char *)qfs_gamedir->dir.def);
if (qfs_gamedir->dir.skins)
free ((char *)qfs_gamedir->dir.skins);
if (qfs_gamedir->dir.models)
free ((char *)qfs_gamedir->dir.models);
if (qfs_gamedir->dir.sound)
free ((char *)qfs_gamedir->dir.sound);
if (qfs_gamedir->dir.maps)
free ((char *)qfs_gamedir->dir.maps);
if (qfs_gamedir->dir.shots)
free ((char *)qfs_gamedir->dir.shots);
free (qfs_gamedir);
}
while (qfs_vpaths) {
vpath_t *next = qfs_vpaths->next;
delete_vpath (qfs_vpaths);
qfs_vpaths = next;
}
}
static void
qfs_build_gamedir (const char **list)
{
@ -584,33 +620,7 @@ qfs_build_gamedir (const char **list)
qfs_set_var (vars, "game", qfs_game);
if (qfs_gamedir) {
if (qfs_gamedir->name)
free ((char *)qfs_gamedir->name);
if (qfs_gamedir->gamedir)
free ((char *)qfs_gamedir->gamedir);
if (qfs_gamedir->path)
free ((char *)qfs_gamedir->path);
if (qfs_gamedir->gamecode)
free ((char *)qfs_gamedir->gamecode);
if (qfs_gamedir->dir.def)
free ((char *)qfs_gamedir->dir.def);
if (qfs_gamedir->dir.skins)
free ((char *)qfs_gamedir->dir.skins);
if (qfs_gamedir->dir.models)
free ((char *)qfs_gamedir->dir.models);
if (qfs_gamedir->dir.sound)
free ((char *)qfs_gamedir->dir.sound);
if (qfs_gamedir->dir.maps)
free ((char *)qfs_gamedir->dir.maps);
free (qfs_gamedir);
}
while (qfs_vpaths) {
vpath_t *next = qfs_vpaths->next;
delete_vpath (qfs_vpaths);
qfs_vpaths = next;
}
qfs_free_gamedir ();
for (j = 0; list[j]; j++)
;
@ -829,13 +839,10 @@ QFS_WriteFile (const char *filename, const void *data, int len)
Qclose (f);
}
static int_findfile_t *
qfs_findfile_search (const vpath_t *vpath, const searchpath_t *sp,
const char **fnames)
static int_findfile_t found;
static void
clear_findfile (void)
{
static int_findfile_t found;
const char **fn;
found.ff.vpath = 0;
found.ff.in_pak = false;
found.pack = 0;
@ -849,6 +856,15 @@ qfs_findfile_search (const vpath_t *vpath, const searchpath_t *sp,
free ((char *) found.path);
found.path = 0;
}
}
static int_findfile_t *
qfs_findfile_search (const vpath_t *vpath, const searchpath_t *sp,
const char **fnames)
{
const char **fn;
clear_findfile ();
// is the element a pak file?
if (sp->pack) {
dpackfile_t *packfile = 0;
@ -1456,11 +1472,13 @@ qfs_path_cvar (void *data, const cvar_t *cvar)
static void
qfs_shutdown (void *data)
{
while (qfs_vpaths) {
vpath_t *next = qfs_vpaths->next;
delete_vpath (qfs_vpaths);
qfs_vpaths = next;
}
clear_findfile ();
qfs_free_gamedir ();
PL_Free (qfs_gd_plist);
free ((char *) qfs_userpath);
free (gamedir_callbacks);
ALLOC_FREE_BLOCKS (vpaths);
ALLOC_FREE_BLOCKS (searchpaths);
}
VISIBLE void

View file

@ -213,3 +213,16 @@ Segtext_Find (const segtext_t *st, const char *tag)
return chunk->text;
return 0;
}
static void
segtext_shutdown (void *data)
{
ALLOC_FREE_BLOCKS (chunks);
ALLOC_FREE_BLOCKS (texts);
}
static void __attribute__((constructor))
segtext_init (void)
{
Sys_RegisterShutdown (segtext_shutdown, 0);
}

View file

@ -721,3 +721,16 @@ set_as_string (const set_t *set)
dstring_clearstr (str);
return set_to_dstring_r (&static_set_pool, str, set);
}
static void
set_shutdown (void *data)
{
ALLOC_FREE_BLOCKS (static_set_pool.set);
ALLOC_FREE_BLOCKS (static_set_pool.set_iter);
}
static void __attribute__((constructor))
set_init (void)
{
Sys_RegisterShutdown (set_shutdown, 0);
}

View file

@ -536,22 +536,6 @@ Sys_Init_Cvars (void)
Cvar_Register (&sys_sleep_cvar, 0, 0);
}
void
Sys_Shutdown (void)
{
shutdown_list_t *t;
while (shutdown_list) {
void (*func) (void *) = shutdown_list->func;
void *data = shutdown_list->data;
t = shutdown_list;
shutdown_list = shutdown_list->next;
free (t);
func (data);
}
}
VISIBLE void
Sys_Quit (void)
{
@ -1231,3 +1215,45 @@ Sys_UniqueFile (dstring_t *name, const char *prefix, const char *suffix,
seq++;
}
}
void
Sys_Shutdown (void)
{
shutdown_list_t *t;
while (shutdown_list) {
void (*func) (void *) = shutdown_list->func;
void *data = shutdown_list->data;
t = shutdown_list;
shutdown_list = shutdown_list->next;
free (t);
func (data);
}
while (free_sh) {
__auto_type t = free_sh->next;
free (free_sh);
free_sh = t;
}
while (sh_stack) {
__auto_type t = sh_stack->next;
free (sh_stack);
sh_stack = t;
}
while (error_handler_freelist) {
__auto_type t = error_handler_freelist->next;
free (error_handler_freelist);
error_handler_freelist = t;
}
while (error_handler) {
__auto_type t = error_handler->next;
free (error_handler);
error_handler = t;
}
if (sys_print_msg) {
dstring_delete (sys_print_msg);
}
if (sys_debuglog_data) {
dstring_delete (sys_debuglog_data);
}
}

View file

@ -11,6 +11,7 @@
#include <stdio.h>
#include "QF/segtext.h"
#include "QF/sys.h"
static const char *test_string =
"blah\n"
@ -83,5 +84,7 @@ main (int argc, const char **argv)
res = 1;
}
}
Segtext_delete (st);
Sys_Shutdown ();
return res;
}

View file

@ -38,6 +38,7 @@
#include <stdarg.h>
#include "QF/dstring.h"
#include "QF/sys.h"
#include "QF/va.h"
struct va_ctx_s {
@ -46,6 +47,8 @@ struct va_ctx_s {
int str_index;
};
static va_ctx_t *default_va_ctx;
VISIBLE va_ctx_t *
va_create_context (int buffers)
{
@ -74,15 +77,14 @@ va_destroy_context (va_ctx_t *ctx)
VISIBLE const char *
va (va_ctx_t *ctx, const char *fmt, ...)
{
static va_ctx_t *_ctx;
va_list args;
dstring_t *dstr;
if (!ctx) {
if (!_ctx) {
_ctx = va_create_context (4);
if (!default_va_ctx) {
default_va_ctx = va_create_context (4);
}
ctx = _ctx;
ctx = default_va_ctx;
}
dstr = ctx->strings[ctx->str_index++ % ctx->num_strings];
@ -107,3 +109,17 @@ nva (const char *fmt, ...)
return dstring_freeze (string);
}
static void
va_shutdown (void *data)
{
if (default_va_ctx) {
va_destroy_context (default_va_ctx);
}
}
static void __attribute__((constructor))
va_init (void)
{
Sys_RegisterShutdown (va_shutdown, 0);
}