From ebb8a0d73875f6df43bb23b8c3777ac2e6d4d87a Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Wed, 14 Sep 2022 19:56:33 +0200 Subject: [PATCH] day 25: memory cleanup, simplify puzzle input read --- 2021/day25/Makefile | 22 ++++++++-------- 2021/day25/aoc-c.c | 61 +++++++++++++++++++++++++++++++++------------ 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/2021/day25/Makefile b/2021/day25/Makefile index 08af8f4..08142b9 100644 --- a/2021/day25/Makefile +++ b/2021/day25/Makefile @@ -24,23 +24,23 @@ LDLIB := -l$(LIB) export LD_LIBRARY_PATH = $(LIBDIR) -CFLAGS += -std=gnu99 -CFLAGS += -O2 -CFLAGS += -g +CFLAGS += -std=gnu99 +CFLAGS += -O2 +CFLAGS += -g # for gprof #CFLAGS += -pg -CFLAGS += -Wall -CFLAGS += -Wextra -CFLAGS += -march=native +CFLAGS += -Wall +CFLAGS += -Wextra +CFLAGS += -march=native # Next one may be useful for valgrind (some invalid instructions) # CFLAGS += -mno-tbm -CFLAGS += -Wmissing-declarations -CFLAGS += -Wno-unused-result +CFLAGS += -Wmissing-declarations +CFLAGS += -Wno-unused-result -CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c) -CFLAGS += -DDEBUG_POOL # memory pools management +CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c) +CFLAGS += -DDEBUG_POOL # memory pools management -TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n" +TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n" export PATH := .:$(PATH) .PHONY: clean all compile assembly memcheck memcheck1 memcheck2 ex1 ex2 diff --git a/2021/day25/aoc-c.c b/2021/day25/aoc-c.c index 97203e4..b002888 100644 --- a/2021/day25/aoc-c.c +++ b/2021/day25/aoc-c.c @@ -112,29 +112,57 @@ static int step(struct map *map) } /** - * read-input() - read cuncumber map into memory. + * map_release() - release a map structure memory. + * @map: A pointer on a map structure. * */ +static void map_release(struct map *map) +{ + if (map) { + if (map->cur) + free(map->cur); + if (map->next) + free(map->next); + free(map); + } +} + +/** + * read_input() - read cuncumber map into memory. + * + * In case of success, the map structure and its cur and array components + * should be released for example by calling map_release(). + * + * Return: a pointer to a map structure or NULL if failure. + */ static struct map *read_input() { size_t alloc = 0; ssize_t buflen; - struct map *map=malloc(sizeof(struct map)); + struct map *map; - if (map) { - map->cur = NULL; - /* read whole input, we will keep '\n' and avoit useless splitting */ - buflen = getdelim(&map->cur, &alloc, '\0', stdin); - map->next = strdup(map->cur); - map->ncols = strchr(map->cur, '\n') - map->cur; - /* we suppose there is nothing after the last input data last line - * Therefore last char of input is '\n', at position (bufflen - 1) - */ - map->nrows = (buflen - 1) / map->ncols; + /* use calloc() to ensure cur & next are set to NULL */ + if (!(map = calloc(1, sizeof(struct map)))) + goto end; - log(2, "buflen=%ld ncols=%d nrows=%d lastnl=%ld\n", buflen, map->ncols, - map->nrows, strrchr(map->cur, '\n') - map->cur); - } + /* read whole input, we will keep '\n' and avoid useless '\0' splitting */ + if ((buflen = getdelim(&map->cur, &alloc, '\0', stdin)) < 0) + goto freemem; + if (!(map->next = strdup(map->cur))) + goto freemem; + map->ncols = strchr(map->cur, '\n') - map->cur; + /* next line works if there is nothing after the last input data last line, + * i.e. if last char of input (at position bufflen - 1) is the '\n' on the + * last valid puzzle line. + */ + map->nrows = (buflen - 1) / map->ncols; + + log(2, "buflen=%ld ncols=%d nrows=%d lastnl=%ld\n", buflen, map->ncols, + map->nrows, strrchr(map->cur, '\n') - map->cur); + goto end; +freemem: + map_release(map); +end: return map; } @@ -173,9 +201,10 @@ int main(int ac, char **av) log(2, "+++ after step %d\n", cur); print_map(map, 0); } + printf("%s : res=%d\n", *av, cur); + map_release(map); } - printf("%s : res=%d\n", *av, cur); exit(0); }