Memory management and other fixes from James H.

[originally from svn r8596]
This commit is contained in:
Simon Tatham
2009-06-17 20:01:45 +00:00
parent 3cd83d05e8
commit 0687980f0c
9 changed files with 46 additions and 22 deletions

View File

@ -2244,6 +2244,8 @@ static game_state *execute_move(game_state *state, char *move)
if (sscanf(move, "%d,%d,%d,%d,%d%n", if (sscanf(move, "%d,%d,%d,%d,%d%n",
&x1, &y1, &x2, &y2, &nl, &n) != 5) &x1, &y1, &x2, &y2, &nl, &n) != 5)
goto badmove; goto badmove;
if (!INGRID(ret, x1, y1) || !INGRID(ret, x2, y2))
goto badmove;
is1 = INDEX(ret, gridi, x1, y1); is1 = INDEX(ret, gridi, x1, y1);
is2 = INDEX(ret, gridi, x2, y2); is2 = INDEX(ret, gridi, x2, y2);
if (!is1 || !is2) goto badmove; if (!is1 || !is2) goto badmove;
@ -2253,6 +2255,8 @@ static game_state *execute_move(game_state *state, char *move)
if (sscanf(move, "%d,%d,%d,%d%n", if (sscanf(move, "%d,%d,%d,%d%n",
&x1, &y1, &x2, &y2, &n) != 4) &x1, &y1, &x2, &y2, &n) != 4)
goto badmove; goto badmove;
if (!INGRID(ret, x1, y1) || !INGRID(ret, x2, y2))
goto badmove;
is1 = INDEX(ret, gridi, x1, y1); is1 = INDEX(ret, gridi, x1, y1);
is2 = INDEX(ret, gridi, x2, y2); is2 = INDEX(ret, gridi, x2, y2);
if (!is1 || !is2) goto badmove; if (!is1 || !is2) goto badmove;
@ -2261,6 +2265,8 @@ static game_state *execute_move(game_state *state, char *move)
if (sscanf(move, "%d,%d%n", if (sscanf(move, "%d,%d%n",
&x1, &y1, &n) != 2) &x1, &y1, &n) != 2)
goto badmove; goto badmove;
if (!INGRID(ret, x1, y1))
goto badmove;
is1 = INDEX(ret, gridi, x1, y1); is1 = INDEX(ret, gridi, x1, y1);
if (!is1) goto badmove; if (!is1) goto badmove;
island_togglemark(is1); island_togglemark(is1);

View File

@ -1138,7 +1138,7 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
static game_state *execute_move(game_state *state, char *move) static game_state *execute_move(game_state *state, char *move)
{ {
game_state *new_state; game_state *new_state = NULL;
const int sz = state->shared->params.w * state->shared->params.h; const int sz = state->shared->params.w * state->shared->params.h;
if (*move == 's') { if (*move == 's') {
@ -1149,18 +1149,18 @@ static game_state *execute_move(game_state *state, char *move)
} else { } else {
int value; int value;
char *endptr, *delim = strchr(move, '_'); char *endptr, *delim = strchr(move, '_');
if (!delim) return NULL; if (!delim) goto err;
value = strtol(delim+1, &endptr, 0); value = strtol(delim+1, &endptr, 0);
if (*endptr || endptr == delim+1) return NULL; if (*endptr || endptr == delim+1) goto err;
if (value < 0 || value > 9) return NULL; if (value < 0 || value > 9) goto err;
new_state = dup_game(state); new_state = dup_game(state);
while (*move) { while (*move) {
const int i = strtol(move, &endptr, 0); const int i = strtol(move, &endptr, 0);
if (endptr == move) return NULL; if (endptr == move) goto err;
if (i < 0 || i >= sz) return NULL; if (i < 0 || i >= sz) goto err;
new_state->board[i] = value; new_state->board[i] = value;
if (*endptr == '_') break; if (*endptr == '_') break;
if (*endptr != ',') return NULL; if (*endptr != ',') goto err;
move = endptr + 1; move = endptr + 1;
} }
} }
@ -1181,6 +1181,10 @@ static game_state *execute_move(game_state *state, char *move)
} }
return new_state; return new_state;
err:
if (new_state) free_game(new_state);
return NULL;
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -365,7 +365,7 @@ static char *game_text_format(game_state *state)
case s_tile: case s_tile:
if (sp->flags & F_TILE_ASSOC) { if (sp->flags & F_TILE_ASSOC) {
space *dot = sp2dot(state, sp->x, sp->y); space *dot = sp2dot(state, sp->x, sp->y);
if (dot->flags & F_DOT) if (dot && dot->flags & F_DOT)
*p++ = (dot->flags & F_DOT_BLACK) ? 'B' : 'W'; *p++ = (dot->flags & F_DOT_BLACK) ? 'B' : 'W';
else else
*p++ = '?'; /* association with not-a-dot. */ *p++ = '?'; /* association with not-a-dot. */
@ -1450,6 +1450,7 @@ generate:
state = copy2; state = copy2;
} }
} }
sfree(posns);
} }
#endif #endif

View File

@ -727,6 +727,7 @@ static void place_lights(game_state *state, random_state *rs)
debug_state(state); debug_state(state);
assert(!"place_lights failed to resolve overlapping lights!"); assert(!"place_lights failed to resolve overlapping lights!");
} }
sfree(numindices);
} }
/* Fills in all black squares with numbers of adjacent lights. */ /* Fills in all black squares with numbers of adjacent lights. */

3
map.c
View File

@ -1373,6 +1373,7 @@ static int map_solver(struct solver_scratch *sc,
*/ */
} }
sfree(origcolouring);
sfree(subcolouring); sfree(subcolouring);
free_scratch(rsc); free_scratch(rsc);
@ -1788,9 +1789,9 @@ static char *validate_desc(game_params *params, char *desc)
map = snewn(2*wh, int); map = snewn(2*wh, int);
ret = parse_edge_list(params, &desc, map); ret = parse_edge_list(params, &desc, map);
sfree(map);
if (ret) if (ret)
return ret; return ret;
sfree(map);
if (*desc != ',') if (*desc != ',')
return "Expected comma before clue list"; return "Expected comma before clue list";

View File

@ -947,6 +947,7 @@ int midend_num_presets(midend *me)
me->ourgame->encode_params(preset, TRUE); me->ourgame->encode_params(preset, TRUE);
me->npresets++; me->npresets++;
} }
sfree(e);
} }
} }

7
net.c
View File

@ -950,8 +950,10 @@ static void perturb(int w, int h, unsigned char *tiles, int wrapping,
} }
sfree(perim2); sfree(perim2);
if (i == nperim) if (i == nperim) {
sfree(perimeter);
return; /* nothing we can do! */ return; /* nothing we can do! */
}
/* /*
* Now we've constructed a new link, we need to find the entire * Now we've constructed a new link, we need to find the entire
@ -2195,7 +2197,7 @@ static char *interpret_move(game_state *state, game_ui *ui,
static game_state *execute_move(game_state *from, char *move) static game_state *execute_move(game_state *from, char *move)
{ {
game_state *ret; game_state *ret;
int tx, ty, n, noanim, orig; int tx = -1, ty = -1, n, noanim, orig;
ret = dup_game(from); ret = dup_game(from);
@ -2244,6 +2246,7 @@ static game_state *execute_move(game_state *from, char *move)
} }
} }
if (!noanim) { if (!noanim) {
if (tx == -1 || ty == -1) { free_game(ret); return NULL; }
ret->last_rotate_x = tx; ret->last_rotate_x = tx;
ret->last_rotate_y = ty; ret->last_rotate_y = ty;
} }

View File

@ -569,7 +569,7 @@ static char *validate_desc(game_params *params, char *desc)
if (*desc && isdigit((unsigned char)*desc)) { if (*desc && isdigit((unsigned char)*desc)) {
do { do {
p = desc; p = desc;
while (desc && isdigit((unsigned char)*desc)) desc++; while (*desc && isdigit((unsigned char)*desc)) desc++;
n = atoi(p); n = atoi(p);
rowspace -= n+1; rowspace -= n+1;
@ -620,7 +620,7 @@ static game_state *new_game(midend *me, game_params *params, char *desc)
if (*desc && isdigit((unsigned char)*desc)) { if (*desc && isdigit((unsigned char)*desc)) {
do { do {
p = desc; p = desc;
while (desc && isdigit((unsigned char)*desc)) desc++; while (*desc && isdigit((unsigned char)*desc)) desc++;
state->rowdata[state->rowsize * i + state->rowlen[i]++] = state->rowdata[state->rowsize * i + state->rowlen[i]++] =
atoi(p); atoi(p);
} while (*desc++ == '.'); } while (*desc++ == '.');

23
solo.c
View File

@ -582,7 +582,6 @@ static struct block_structure *dup_block_structure(struct block_structure *b)
nb->blocks[i] = nb->blocks_data + i*nb->max_nr_squares; nb->blocks[i] = nb->blocks_data + i*nb->max_nr_squares;
#ifdef STANDALONE_SOLVER #ifdef STANDALONE_SOLVER
nb->blocknames = (char **)smalloc(b->c * b->r *(sizeof(char *)+80));
memcpy(nb->blocknames, b->blocknames, b->c * b->r *(sizeof(char *)+80)); memcpy(nb->blocknames, b->blocknames, b->c * b->r *(sizeof(char *)+80));
{ {
int i; int i;
@ -1697,7 +1696,10 @@ static void solver(int cr, struct block_structure *blocks,
usage->cube = snewn(cr*cr*cr, unsigned char); usage->cube = snewn(cr*cr*cr, unsigned char);
usage->grid = grid; /* write straight back to the input */ usage->grid = grid; /* write straight back to the input */
if (kgrid) { if (kgrid) {
int nclues = kblocks->nr_blocks; int nclues;
assert(kblocks);
nclues = kblocks->nr_blocks;
/* /*
* Allow for expansion of the killer regions, the absolute * Allow for expansion of the killer regions, the absolute
* limit is obviously one region per square. * limit is obviously one region per square.
@ -2589,6 +2591,8 @@ static void solver(int cr, struct block_structure *blocks,
"one solution"); "one solution");
#endif #endif
sfree(usage->sq2region);
sfree(usage->regions);
sfree(usage->cube); sfree(usage->cube);
sfree(usage->row); sfree(usage->row);
sfree(usage->col); sfree(usage->col);
@ -2598,6 +2602,7 @@ static void solver(int cr, struct block_structure *blocks,
free_block_structure(usage->extra_cages); free_block_structure(usage->extra_cages);
sfree(usage->extra_clues); sfree(usage->extra_clues);
} }
if (usage->kclues) sfree(usage->kclues);
sfree(usage); sfree(usage);
solver_free_scratch(scratch); solver_free_scratch(scratch);
@ -3551,13 +3556,8 @@ static char *new_game_desc(game_params *params, random_state *rs,
blocks = alloc_block_structure (c, r, area, cr, cr); blocks = alloc_block_structure (c, r, area, cr, cr);
if (params->killer) {
kblocks = alloc_block_structure (c, r, area, cr, area);
kgrid = snewn(area, digit);
} else {
kblocks = NULL; kblocks = NULL;
kgrid = NULL; kgrid = (params->killer) ? snewn(area, digit) : NULL;
}
#ifdef STANDALONE_SOLVER #ifdef STANDALONE_SOLVER
assert(!"This should never happen, so we don't need to create blocknames"); assert(!"This should never happen, so we don't need to create blocknames");
@ -3587,6 +3587,7 @@ static char *new_game_desc(game_params *params, random_state *rs,
make_blocks_from_whichblock(blocks); make_blocks_from_whichblock(blocks);
if (params->killer) { if (params->killer) {
if (kblocks) free_block_structure(kblocks);
kblocks = gen_killer_cages(cr, rs, params->kdiff > DIFF_KSINGLE); kblocks = gen_killer_cages(cr, rs, params->kdiff > DIFF_KSINGLE);
} }
@ -3753,6 +3754,11 @@ static char *new_game_desc(game_params *params, random_state *rs,
desc = encode_puzzle_desc(params, grid, blocks, kgrid, kblocks); desc = encode_puzzle_desc(params, grid, blocks, kgrid, kblocks);
sfree(grid); sfree(grid);
free_block_structure(blocks);
if (params->killer) {
free_block_structure(kblocks);
sfree(kgrid);
}
return desc; return desc;
} }
@ -4150,6 +4156,7 @@ static void free_game(game_state *state)
sfree(state->immutable); sfree(state->immutable);
sfree(state->pencil); sfree(state->pencil);
sfree(state->grid); sfree(state->grid);
if (state->kgrid) sfree(state->kgrid);
sfree(state); sfree(state);
} }