commit c80091d4748c63f34b4320d8fcd395a85ab7fba2
parent ece9d3159b43d57b23b7415799dd7965b36421c3
Author: Michael Neuper <michael@michaelneuper.com>
Date: Tue, 11 Nov 2025 08:41:52 +0200
remove goto's and fix memory leak
Diffstat:
| M | life.c | | | 73 | ++++++++++++++++++++++++++++++++++++++++--------------------------------- |
1 file changed, 40 insertions(+), 33 deletions(-)
diff --git a/life.c b/life.c
@@ -54,12 +54,12 @@ void randomize_grid(Grid *grid);
/* --- main routine --------------------------------------------------------- */
-int main(int argc, char *argv[]) {
+int main(void) {
init_screen();
game_loop();
cleanup();
- return 0;
+ return EXIT_SUCCESS;
}
/* -------------------------------------------------------------------------- */
@@ -72,7 +72,13 @@ void game_loop() {
Grid *cur = init_grid(rows, cols);
Grid *next = init_grid(rows, cols);
- if (!(cur && next)) goto err;
+ if (!(cur && next)) {
+ cleanup();
+ if (cur) free_grid(cur);
+ if (next) free_grid(next);
+ fprintf(stderr, "Something terrible has happened.\n");
+ exit(1);
+ }
struct timespec ts;
ts.tv_sec = 0;
@@ -107,14 +113,6 @@ void game_loop() {
free_grid(cur);
free_grid(next);
- return;
-
-err:
- cleanup();
- if (cur) free_grid(cur);
- if (next) free_grid(next);
- fprintf(stderr, "Something terrible has happened.\n");
- exit(1);
}
void tick(const Grid *cur, Grid *next) {
@@ -180,12 +178,26 @@ Grid *init_grid(size_t rows, size_t cols) {
State **cells = malloc(rows * sizeof(State *));
Grid *grid = malloc(sizeof(Grid));
- if (!(grid && cells)) goto err;
+ if (!(grid && cells)) {
+ if (cells) free(cells);
+ if (grid) free(grid);
+
+ return NULL;
+ }
for (size_t i = 0; i < rows; i++) {
cells[i] = malloc(cols * sizeof(State));
- if (!cells[i]) goto err; // FIXME memory leak
+ if (!cells[i]) {
+ for (size_t j = 0; j < i; j++)
+ free(cells[i]);
+ free(cells);
+ free(grid);
+
+ return NULL;
+ }
+
+ // initialize all cells to DEAD
for (size_t j = 0; j < cols; j++) {
cells[i][j] = DEAD;
}
@@ -196,12 +208,6 @@ Grid *init_grid(size_t rows, size_t cols) {
grid->cols = cols;
return grid;
-
-err:
- if (cells) free(cells);
- if (grid) free(grid);
-
- return NULL;
}
void free_grid(Grid *grid) {
@@ -216,6 +222,7 @@ void free_grid(Grid *grid) {
void print_grid(const Grid *grid) {
for (size_t i = 0; i < grid->rows; i++) {
for (size_t j = 0; j < grid->cols; j++) {
+ // print ' ' for dead cells to avoid having to clear the screen
print_char(i, j, grid->cells[i][j] ? '#' : ' ', 0);
}
}
@@ -224,6 +231,8 @@ void print_grid(const Grid *grid) {
}
void set_grid(Grid *grid) {
+ bool paused = true;
+
struct {
size_t row, col;
} curs = {grid->rows / 2, grid->cols / 2};
@@ -231,32 +240,32 @@ void set_grid(Grid *grid) {
init_pair(CURS_COL, COLOR_BLUE, COLOR_BLACK);
print_char(curs.row, curs.col, '*', CURS_COL);
- while (true) {
+ while (paused) {
int key = getch();
switch (key) {
case KEY_UP:
case 'k':
case 'w':
- curs.row -= 1;
+ curs.row--;
break;
case KEY_LEFT:
case 'h':
case 'a':
- curs.col -= 1;
+ curs.col--;
break;
case KEY_DOWN:
case 'j':
case 's':
- curs.row += 1;
+ curs.row++;
break;
case KEY_RIGHT:
case 'l':
case 'd':
- curs.col += 1;
+ curs.col++;
break;
case 't':
@@ -267,19 +276,22 @@ void set_grid(Grid *grid) {
randomize_grid(grid);
break;
+ case 'q':
+ free_grid(grid);
+ cleanup();
+ exit(0);
+
case '\n':
case '\r':
case ' ':
case 'e':
- return;
-
- case 'q':
- goto quit;
+ paused = false;
default:
continue;
}
+ // wrap cursor around screen
curs.row = (curs.row + grid->rows) % grid->rows;
curs.col = (curs.col + grid->cols) % grid->cols;
@@ -287,11 +299,6 @@ void set_grid(Grid *grid) {
print_grid(grid);
print_char(curs.row, curs.col, '*', CURS_COL);
}
-
-quit:
- free_grid(grid);
- cleanup();
- exit(0);
}
void randomize_grid(Grid *grid) {