From 8dbdea6ac44a595ca6a11bc97d75c7749924ca7d Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Thu, 2 Jan 2025 17:53:40 +0000 Subject: [PATCH] Fix some memory leaks --- engine/engine.c | 1 + game/main.c | 69 +++++++++++++++++++++++++++---------------------- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/engine/engine.c b/engine/engine.c index adf86f9..1fa05d3 100644 --- a/engine/engine.c +++ b/engine/engine.c @@ -93,6 +93,7 @@ int main(int argc, char *argv[]) quit: game_teardown(gamemem); + free(gamemem); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); diff --git a/game/main.c b/game/main.c index bc066b3..d7fed9a 100644 --- a/game/main.c +++ b/game/main.c @@ -164,6 +164,15 @@ static inline bool tilepassable(const map_t map, int x, int y) return true; } +static inline int propint(xmlNodePtr node, const char *prop) +{ + xmlChar *str = xmlGetProp(node, (const xmlChar *)prop); + assert(str); + int val = atoi((const char *)str); + xmlFree(str); + return val; +} + static void maploadlayer(map_t map, xmlNodePtr layernode, int layeridx) { xmlNodePtr node = layernode->xmlChildrenNode; @@ -178,11 +187,8 @@ static void maploadlayer(map_t map, xmlNodePtr layernode, int layeridx) if (0 != xmlStrcmp(node->name, (const xmlChar *)"chunk")) continue; - xmlChar *x_attr, *y_attr; - x_attr = xmlGetProp(node, (const xmlChar *)"x"); - y_attr = xmlGetProp(node, (const xmlChar *)"y"); - const int chunk_x = atoi((const char *)x_attr); - const int chunk_y = atoi((const char *)y_attr); + const int chunk_x = propint(node, "x"); + const int chunk_y = propint(node, "y"); chunk_contents = node->xmlChildrenNode; assert( @@ -243,18 +249,15 @@ objtypeload(gamestate_t *state, const char *templ, SDL_Renderer *renderer) && xmlStrcmp(node->name, (const xmlChar *)"object") != 0) node = node->next; assert(NULL != node); - unsigned id - = atoi((const char *)xmlGetProp(node, (const xmlChar *)"gid")); + unsigned id = propint(node, "gid"); assert(id < MAXOBJTYPES); // Populate objtype struct if not already loaded if (NULL == state->objtypes[id].tex) { state->objtypes[id].src.x = 0; state->objtypes[id].src.y = 0; - state->objtypes[id].src.w - = atoi((const char *)xmlGetProp(node, (const xmlChar *)"width")); - state->objtypes[id].src.h = atoi( - (const char *)xmlGetProp(node, (const xmlChar *)"height")); + state->objtypes[id].src.w = propint(node, "width"); + state->objtypes[id].src.h = propint(node, "height"); node = node->xmlChildrenNode; while (node != NULL @@ -264,24 +267,29 @@ objtypeload(gamestate_t *state, const char *templ, SDL_Renderer *renderer) for (node = node->xmlChildrenNode; NULL != node; node = node->next) { if (xmlStrcmp(node->name, (const xmlChar *)"property") != 0) continue; - const char *key - = (const char *)xmlGetProp(node, (const xmlChar *)"name"); - const char *val - = (const char *)xmlGetProp(node, (const xmlChar *)"value"); - if (strcmp(key, "animframes") == 0) { - state->objtypes[id].animframes = atoi(val); - } else if (strcmp(key, "assetpath") == 0) { - assert(strlen(state->assetdir) + strlen(val) < MAX_PATH_LEN); + xmlChar *key = xmlGetProp(node, (const xmlChar *)"name"); + assert(key); + xmlChar *val = xmlGetProp(node, (const xmlChar *)"value"); + assert(val); + if (xmlStrcmp(key, (const xmlChar *)"animframes") == 0) { + state->objtypes[id].animframes = atoi((const char *)val); + } else if (xmlStrcmp(key, (const xmlChar *)"assetpath") == 0) { + assert( + strlen(state->assetdir) + strlen((const char *)val) + < MAX_PATH_LEN); strcpy(buf, state->assetdir); - strcat(buf, val); + strcat(buf, (const char *)val); state->objtypes[id].tex = IMG_LoadTexture(renderer, buf); assert(NULL != state->objtypes[id].tex); } else { assert(false); } + xmlFree(key); + xmlFree(val); } } + xmlFreeDoc(doc); return id; } @@ -309,26 +317,23 @@ maploadobjects(gamestate_t *state, xmlNodePtr node, SDL_Renderer *renderer) obj_t *o = &state->objcol.buf[state->objcol.n++]; // Load object type - const xmlChar *templ = xmlGetProp(node, (const xmlChar *)"template"); - assert(NULL != templ); + xmlChar *templ = xmlGetProp(node, (const xmlChar *)"template"); + assert(templ); o->type = objtypeload(state, (const char *)templ, renderer); + xmlFree(templ); - // Load object location and set size from objtype - o->pos.x - = atoi((const char *)xmlGetProp(node, (const xmlChar *)"x")); - o->pos.y - = atoi((const char *)xmlGetProp(node, (const xmlChar *)"y")); + // Load object location + o->pos.x = propint(node, "x"); + o->pos.y = propint(node, "y"); } while ((node = node->next) != NULL); } static void mapload(gamestate_t *state, const char *path, SDL_Renderer *renderer) { - xmlDocPtr doc; - xmlNodePtr node; - doc = xmlParseFile(path); + xmlDocPtr doc = xmlParseFile(path); assert(NULL != doc); - node = xmlDocGetRootElement(doc); + xmlNodePtr node = xmlDocGetRootElement(doc); assert(0 == xmlStrcmp(node->name, (const xmlChar *)"map")); node = node->xmlChildrenNode; int layer = 0; @@ -339,6 +344,7 @@ mapload(gamestate_t *state, const char *path, SDL_Renderer *renderer) else if (xmlStrcmp(node->name, (const xmlChar *)"objectgroup") == 0) maploadobjects(state, node, renderer); } while ((node = node->next) != NULL); + xmlFreeDoc(doc); } static void mapdraw(const gamestate_t *state, SDL_Renderer *renderer) @@ -521,6 +527,7 @@ void game_teardown(void *mem) else break; } + free(state->objcol.buf); } gamestatus_t game_evthandle(void *mem, const SDL_Event *evt)