From 0d65bbaaf3f5f63b529acba1b734a989cb9afdf1 Mon Sep 17 00:00:00 2001 From: Jean-loup Gailly Date: Sat, 3 Apr 2010 14:29:42 +0200 Subject: [PATCH] Check all memory allocations to avoid core dump when running out of memory. --- board.c | 6 +++--- board.h | 2 +- distributed/distributed.c | 6 +++--- montecarlo/montecarlo.c | 4 ++-- move.h | 5 +++-- pattern.c | 4 ++-- patternscan/patternscan.c | 4 ++-- patternsp.c | 2 +- playout/elo.c | 4 ++-- playout/light.c | 2 +- playout/moggy.c | 10 +++++----- random/random.c | 2 +- replay/replay.c | 4 ++-- uct/dynkomi.c | 10 +++++----- uct/policy/ucb1.c | 4 ++-- uct/policy/ucb1amaf.c | 4 ++-- uct/prior.c | 6 +++--- uct/tree.c | 30 +++++++----------------------- uct/uct.c | 14 +++++++------- uct/walk.c | 4 ++-- util.h | 29 +++++++++++++++++++++++++++++ 21 files changed, 85 insertions(+), 71 deletions(-) diff --git a/board.c b/board.c index 48428c3..9c005a8 100644 --- a/board.c +++ b/board.c @@ -48,7 +48,7 @@ board_setup(struct board *b) struct board * board_init(void) { - struct board *b = malloc(sizeof(struct board)); + struct board *b = malloc2(sizeof(struct board)); board_setup(b); // Default setup @@ -97,7 +97,7 @@ board_copy(struct board *b2, struct board *b1) #else int pbsize = 0; #endif - void *x = malloc(bsize + gsize + fsize + psize + nsize + hsize + gisize + csize + ssize + p3size + tsize + tqsize + pbsize * 2); + void *x = malloc2(bsize + gsize + fsize + psize + nsize + hsize + gisize + csize + ssize + p3size + tsize + tqsize + pbsize * 2); memcpy(x, b1->b, bsize + gsize + fsize + psize + nsize + hsize + gisize + csize + ssize + p3size + tsize + tqsize + pbsize * 2); b2->b = x; x += bsize; b2->g = x; x += gsize; @@ -185,7 +185,7 @@ board_resize(struct board *board, int size) #else int pbsize = 0; #endif - void *x = malloc(bsize + gsize + fsize + psize + nsize + hsize + gisize + csize + ssize + p3size + tsize + tqsize + pbsize * 2); + void *x = malloc2(bsize + gsize + fsize + psize + nsize + hsize + gisize + csize + ssize + p3size + tsize + tqsize + pbsize * 2); memset(x, 0, bsize + gsize + fsize + psize + nsize + hsize + gisize + csize + ssize + p3size + tsize + tqsize + pbsize * 2); board->b = x; x += bsize; board->g = x; x += gsize; diff --git a/board.h b/board.h index 1afc396..e3a1b5a 100644 --- a/board.h +++ b/board.h @@ -5,10 +5,10 @@ #include #include +#include "util.h" #include "stone.h" #include "move.h" #include "probdist.h" -#include "util.h" struct features_gamma; diff --git a/distributed/distributed.c b/distributed/distributed.c index 382e326..f0aa015 100644 --- a/distributed/distributed.c +++ b/distributed/distributed.c @@ -733,7 +733,7 @@ distributed_dead_group_list(struct engine *e, struct board *b, struct move_queue static struct distributed * distributed_state_init(char *arg, struct board *b) { - struct distributed *dist = calloc(1, sizeof(struct distributed)); + struct distributed *dist = calloc2(1, sizeof(struct distributed)); dist->max_slaves = 100; if (arg) { @@ -761,7 +761,7 @@ distributed_state_init(char *arg, struct board *b) } } - gtp_replies = calloc(dist->max_slaves, sizeof(char *)); + gtp_replies = calloc2(dist->max_slaves, sizeof(char *)); if (!dist->slave_port) { fprintf(stderr, "distributed: missing slave_port\n"); @@ -787,7 +787,7 @@ engine_distributed_init(char *arg, struct board *b) { start_time = time_now(); struct distributed *dist = distributed_state_init(arg, b); - struct engine *e = calloc(1, sizeof(struct engine)); + struct engine *e = calloc2(1, sizeof(struct engine)); e->name = "Distributed Engine"; e->comment = "I'm playing the distributed engine. When I'm losing, I will resign, " "if I think I win, I play until you pass. " diff --git a/montecarlo/montecarlo.c b/montecarlo/montecarlo.c index bc7b8c2..35cc70e 100644 --- a/montecarlo/montecarlo.c +++ b/montecarlo/montecarlo.c @@ -208,7 +208,7 @@ move_found: struct montecarlo * montecarlo_state_init(char *arg, struct board *b) { - struct montecarlo *mc = calloc(1, sizeof(struct montecarlo)); + struct montecarlo *mc = calloc2(1, sizeof(struct montecarlo)); mc->debug_level = 1; mc->gamelen = MC_GAMELEN; @@ -265,7 +265,7 @@ struct engine * engine_montecarlo_init(char *arg, struct board *b) { struct montecarlo *mc = montecarlo_state_init(arg, b); - struct engine *e = calloc(1, sizeof(struct engine)); + struct engine *e = calloc2(1, sizeof(struct engine)); e->name = "MonteCarlo Engine"; e->comment = "I'm playing in Monte Carlo. When we both pass, I will consider all the stones on the board alive. If you are reading this, write 'yes'. Please bear with me at the game end, I need to fill the whole board; if you help me, we will both be happier. Filling the board will not lose points (NZ rules)."; e->genmove = montecarlo_genmove; diff --git a/move.h b/move.h index efdbd6e..93bfbb5 100644 --- a/move.h +++ b/move.h @@ -4,6 +4,7 @@ #include #include +#include "util.h" #include "stone.h" typedef int coord_t; @@ -56,7 +57,7 @@ struct move { static inline coord_t * coord_init(int x, int y, int size) { - coord_t *c = calloc(1, sizeof(coord_t)); + coord_t *c = calloc2(1, sizeof(coord_t)); *c = x + y * size; return c; } @@ -64,7 +65,7 @@ coord_init(int x, int y, int size) static inline coord_t * coord_copy(coord_t c) { - coord_t *c2 = calloc(1, sizeof(coord_t)); + coord_t *c2 = calloc2(1, sizeof(coord_t)); memcpy(c2, &c, sizeof(c)); return c2; } diff --git a/pattern.c b/pattern.c index e2e0c51..3e9ce91 100644 --- a/pattern.c +++ b/pattern.c @@ -529,11 +529,11 @@ const char *features_gamma_filename = "patterns.gamma"; struct features_gamma * features_gamma_init(struct pattern_config *pc, const char *file) { - struct features_gamma *fg = calloc(1, sizeof(*fg)); + struct features_gamma *fg = calloc2(1, sizeof(*fg)); fg->pc = pc; for (int i = 0; i < FEAT_MAX; i++) { int n = feature_payloads(pc, i); - fg->gamma[i] = malloc(n * sizeof(fg->gamma[0][0])); + fg->gamma[i] = malloc2(n * sizeof(fg->gamma[0][0])); for (int j = 0; j < n; j++) { fg->gamma[i][j] = 1.0f; } diff --git a/patternscan/patternscan.c b/patternscan/patternscan.c index 74d2c6c..9ea0a25 100644 --- a/patternscan/patternscan.c +++ b/patternscan/patternscan.c @@ -291,7 +291,7 @@ patternscan_done(struct engine *e) struct patternscan * patternscan_state_init(char *arg) { - struct patternscan *ps = calloc(1, sizeof(struct patternscan)); + struct patternscan *ps = calloc2(1, sizeof(struct patternscan)); int xspat = -1; ps->debug_level = 1; @@ -406,7 +406,7 @@ struct engine * engine_patternscan_init(char *arg, struct board *b) { struct patternscan *ps = patternscan_state_init(arg); - struct engine *e = calloc(1, sizeof(struct engine)); + struct engine *e = calloc2(1, sizeof(struct engine)); e->name = "PatternScan Engine"; e->comment = "You cannot play Pachi with this engine, it is intended for special development use - scanning of games fed to it as GTP streams for various pattern features."; e->genmove = patternscan_genmove; diff --git a/patternsp.c b/patternsp.c index 77d21e5..d2dc7ba 100644 --- a/patternsp.c +++ b/patternsp.c @@ -340,7 +340,7 @@ spatial_dict_init(bool will_append) return NULL; } - struct spatial_dict *dict = calloc(1, sizeof(*dict)); + struct spatial_dict *dict = calloc2(1, sizeof(*dict)); /* We create a dummy record for index 0 that we will * never reference. This is so that hash value 0 can * represent "no value". */ diff --git a/playout/elo.c b/playout/elo.c index ffea568..47a5a80 100644 --- a/playout/elo.c +++ b/playout/elo.c @@ -228,8 +228,8 @@ playout_elo_callback(struct playout_policy *p, playout_elo_callbackp callback, v struct playout_policy * playout_elo_init(char *arg, struct board *b) { - struct playout_policy *p = calloc(1, sizeof(*p)); - struct elo_policy *pp = calloc(1, sizeof(*pp)); + struct playout_policy *p = calloc2(1, sizeof(*p)); + struct elo_policy *pp = calloc2(1, sizeof(*pp)); p->data = pp; p->choose = playout_elo_choose; p->assess = playout_elo_assess; diff --git a/playout/light.c b/playout/light.c index f38331c..992e94d 100644 --- a/playout/light.c +++ b/playout/light.c @@ -22,7 +22,7 @@ playout_light_choose(struct playout_policy *p, struct board *b, enum stone to_pl struct playout_policy * playout_light_init(char *arg, struct board *b) { - struct playout_policy *p = calloc(1, sizeof(*p)); + struct playout_policy *p = calloc2(1, sizeof(*p)); p->choose = playout_light_choose; if (arg) diff --git a/playout/moggy.c b/playout/moggy.c index 0b3e6ff..4648809 100644 --- a/playout/moggy.c +++ b/playout/moggy.c @@ -123,10 +123,10 @@ board_state_init(struct board *b) #endif } if (!ss) { - ss = malloc(sizeof(*ss)); + ss = malloc2(sizeof(*ss)); ss->bsize2 = board_size2(b); - ss->groups = malloc(board_size2(b) * sizeof(*ss->groups)); - ss->groups_known = malloc(board_size2(b) / 8 + 1); + ss->groups = malloc2(board_size2(b) * sizeof(*ss->groups)); + ss->groups_known = malloc2(board_size2(b) / 8 + 1); } ss->hash = b->hash; memset(ss->groups_known, 0, board_size2(b) / 8 + 1); @@ -878,8 +878,8 @@ playout_moggy_permit(struct playout_policy *p, struct board *b, struct move *m) struct playout_policy * playout_moggy_init(char *arg, struct board *b) { - struct playout_policy *p = calloc(1, sizeof(*p)); - struct moggy_policy *pp = calloc(1, sizeof(*pp)); + struct playout_policy *p = calloc2(1, sizeof(*p)); + struct moggy_policy *pp = calloc2(1, sizeof(*pp)); p->data = pp; p->choose = playout_moggy_choose; p->assess = playout_moggy_assess; diff --git a/random/random.c b/random/random.c index 029a96b..c68f5a6 100644 --- a/random/random.c +++ b/random/random.c @@ -23,7 +23,7 @@ random_genmove(struct engine *e, struct board *b, struct time_info *ti, enum sto struct engine * engine_random_init(char *arg, struct board *b) { - struct engine *e = calloc(1, sizeof(struct engine)); + struct engine *e = calloc2(1, sizeof(struct engine)); e->name = "RandomMove Engine"; e->comment = "I just make random moves. I won't pass as long as there is a place on the board where I can play. When we both pass, I will consider all the stones on the board alive."; e->genmove = random_genmove; diff --git a/replay/replay.c b/replay/replay.c index 4894f08..dd7c72d 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -56,7 +56,7 @@ have_move: struct replay * replay_state_init(char *arg, struct board *b) { - struct replay *r = calloc(1, sizeof(struct replay)); + struct replay *r = calloc2(1, sizeof(struct replay)); r->debug_level = 1; @@ -106,7 +106,7 @@ struct engine * engine_replay_init(char *arg, struct board *b) { struct replay *r = replay_state_init(arg, b); - struct engine *e = calloc(1, sizeof(struct engine)); + struct engine *e = calloc2(1, sizeof(struct engine)); e->name = "PlayoutReplay Engine"; e->comment = "I select moves blindly according to playout policy. I won't pass as long as there is a place on the board where I can play. When we both pass, I will consider all the stones on the board alive."; e->genmove = replay_genmove; diff --git a/uct/dynkomi.c b/uct/dynkomi.c index 1d3408a..0cdea2d 100644 --- a/uct/dynkomi.c +++ b/uct/dynkomi.c @@ -26,7 +26,7 @@ generic_done(struct uct_dynkomi *d) struct uct_dynkomi * uct_dynkomi_init_none(struct uct *u, char *arg, struct board *b) { - struct uct_dynkomi *d = calloc(1, sizeof(*d)); + struct uct_dynkomi *d = calloc2(1, sizeof(*d)); d->uct = u; d->permove = NULL; d->persim = NULL; @@ -81,13 +81,13 @@ linear_persim(struct uct_dynkomi *d, struct board *b, struct tree *tree, struct struct uct_dynkomi * uct_dynkomi_init_linear(struct uct *u, char *arg, struct board *b) { - struct uct_dynkomi *d = calloc(1, sizeof(*d)); + struct uct_dynkomi *d = calloc2(1, sizeof(*d)); d->uct = u; d->permove = linear_permove; d->persim = linear_persim; d->done = generic_done; - struct dynkomi_linear *l = calloc(1, sizeof(*l)); + struct dynkomi_linear *l = calloc2(1, sizeof(*l)); d->data = l; if (board_size(b) - 2 >= 19) @@ -313,13 +313,13 @@ adaptive_persim(struct uct_dynkomi *d, struct board *b, struct tree *tree, struc struct uct_dynkomi * uct_dynkomi_init_adaptive(struct uct *u, char *arg, struct board *b) { - struct uct_dynkomi *d = calloc(1, sizeof(*d)); + struct uct_dynkomi *d = calloc2(1, sizeof(*d)); d->uct = u; d->permove = adaptive_permove; d->persim = adaptive_persim; d->done = generic_done; - struct dynkomi_adaptive *a = calloc(1, sizeof(*a)); + struct dynkomi_adaptive *a = calloc2(1, sizeof(*a)); d->data = a; if (board_size(b) - 2 >= 19) diff --git a/uct/policy/ucb1.c b/uct/policy/ucb1.c index 7bb7245..8cbeb19 100644 --- a/uct/policy/ucb1.c +++ b/uct/policy/ucb1.c @@ -73,8 +73,8 @@ ucb1_update(struct uct_policy *p, struct tree *tree, struct tree_node *node, enu struct uct_policy * policy_ucb1_init(struct uct *u, char *arg) { - struct uct_policy *p = calloc(1, sizeof(*p)); - struct ucb1_policy *b = calloc(1, sizeof(*b)); + struct uct_policy *p = calloc2(1, sizeof(*p)); + struct ucb1_policy *b = calloc2(1, sizeof(*b)); p->uct = u; p->data = b; p->descend = ucb1_descend; diff --git a/uct/policy/ucb1amaf.c b/uct/policy/ucb1amaf.c index 0cf2ea3..70333f5 100644 --- a/uct/policy/ucb1amaf.c +++ b/uct/policy/ucb1amaf.c @@ -230,8 +230,8 @@ ucb1amaf_update(struct uct_policy *p, struct tree *tree, struct tree_node *node, struct uct_policy * policy_ucb1amaf_init(struct uct *u, char *arg) { - struct uct_policy *p = calloc(1, sizeof(*p)); - struct ucb1_policy_amaf *b = calloc(1, sizeof(*b)); + struct uct_policy *p = calloc2(1, sizeof(*p)); + struct ucb1_policy_amaf *b = calloc2(1, sizeof(*b)); p->uct = u; p->data = b; p->choose = uctp_generic_choose; diff --git a/uct/prior.c b/uct/prior.c index 59de5b7..1e5e219 100644 --- a/uct/prior.c +++ b/uct/prior.c @@ -138,7 +138,7 @@ uct_prior(struct uct *u, struct tree_node *node, struct prior_map *map) struct uct_prior * uct_prior_init(char *arg, struct board *b) { - struct uct_prior *p = calloc(1, sizeof(struct uct_prior)); + struct uct_prior *p = calloc2(1, sizeof(struct uct_prior)); p->even_eqex = p->policy_eqex = p->b19_eqex = p->eye_eqex = p->ko_eqex = -1; p->cfgdn = -1; @@ -175,7 +175,7 @@ uct_prior_init(char *arg, struct board *b) * 20 wins, 2nd-level neighbors 20 wins; * neighbors are group-transitive. */ p->cfgdn = atoi(optval); optval += strcspn(optval, ":"); - p->cfgd_eqex = calloc(p->cfgdn + 1, sizeof(*p->cfgd_eqex)); + p->cfgd_eqex = calloc2(p->cfgdn + 1, sizeof(*p->cfgd_eqex)); p->cfgd_eqex[0] = 0; for (int i = 1; *optval; i++, optval += strcspn(optval, ":")) { optval++; @@ -201,7 +201,7 @@ uct_prior_init(char *arg, struct board *b) if (p->cfgdn < 0) { int bonuses[] = { 0, p->eqex, p->eqex / 2, p->eqex / 2 }; p->cfgdn = 3; - p->cfgd_eqex = calloc(p->cfgdn + 1, sizeof(*p->cfgd_eqex)); + p->cfgd_eqex = calloc2(p->cfgdn + 1, sizeof(*p->cfgd_eqex)); memcpy(p->cfgd_eqex, bonuses, sizeof(bonuses)); } if (p->cfgdn > TREE_NODE_D_MAX) { diff --git a/uct/tree.c b/uct/tree.c index 947d02d..7f4e8ef 100644 --- a/uct/tree.c +++ b/uct/tree.c @@ -49,11 +49,7 @@ tree_init_node(struct tree *t, coord_t coord, int depth, bool fast_alloc) if (!n) return n; memset(n, 0, sizeof(*n)); } else { - n = calloc(1, sizeof(*n)); - if (!n) { - fprintf(stderr, "tree_init_node(): OUT OF MEMORY\n"); - exit(1); - } + n = calloc2(1, sizeof(*n)); __sync_fetch_and_add(&t->nodes_size, sizeof(*n)); } n->coord = coord; @@ -69,23 +65,15 @@ tree_init_node(struct tree *t, coord_t coord, int depth, bool fast_alloc) struct tree * tree_init(struct board *board, enum stone color, unsigned long max_tree_size, float ltree_aging) { - struct tree *t = calloc(1, sizeof(*t)); - if (!t) { - fprintf(stderr, "tree_init(): OUT OF MEMORY\n"); - exit(1); - } + struct tree *t = calloc2(1, sizeof(*t)); t->board = board; t->max_tree_size = max_tree_size; if (max_tree_size != 0) { /* Allocate one extra node, max_tree_size may not be multiple of node size. */ - t->nodes = malloc(max_tree_size + sizeof(struct tree_node)); + t->nodes = malloc2(max_tree_size + sizeof(struct tree_node)); /* The nodes buffer doesn't need initialization. This is currently * done by tree_init_node to spread the load. Doing a memset for the * entire buffer here would be too slow for large trees (>10 GB). */ - if (!t->nodes) { - fprintf(stderr, "tree_init(): OUT OF MEMORY\n"); - exit(1); - } } /* The root PASS move is only virtual, we never play it. */ t->root = tree_init_node(t, pass, 0, t->nodes); @@ -154,11 +142,7 @@ tree_done_node_detached(struct tree *t, struct tree_node *n) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_t thread; - struct subtree_ctx *ctx = malloc(sizeof(struct subtree_ctx)); - if (!ctx) { - fprintf(stderr, "tree_done_node_detached(): OUT OF MEMORY\n"); - exit(1); - } + struct subtree_ctx *ctx = malloc2(sizeof(struct subtree_ctx)); ctx->t = t; ctx->n = n; pthread_create(&thread, &attr, tree_done_node_worker, ctx); @@ -311,7 +295,7 @@ tree_node_load(FILE *f, struct tree_node *node, int *num) struct tree_node *ni = NULL, *ni_prev = NULL; while (fgetc(f)) { - ni_prev = ni; ni = calloc(1, sizeof(*ni)); + ni_prev = ni; ni = calloc2(1, sizeof(*ni)); if (!node->children) node->children = ni; else @@ -343,7 +327,7 @@ tree_load(struct tree *tree, struct board *b) static struct tree_node * tree_node_copy(struct tree_node *node) { - struct tree_node *n2 = malloc(sizeof(*n2)); + struct tree_node *n2 = malloc2(sizeof(*n2)); *n2 = *node; if (!node->children) return n2; @@ -361,7 +345,7 @@ struct tree * tree_copy(struct tree *tree) { assert(!tree->nodes); - struct tree *t2 = malloc(sizeof(*t2)); + struct tree *t2 = malloc2(sizeof(*t2)); *t2 = *tree; t2->root = tree_node_copy(tree->root); return t2; diff --git a/uct/uct.c b/uct/uct.c index 003ced4..f593742 100644 --- a/uct/uct.c +++ b/uct/uct.c @@ -407,7 +407,7 @@ spawn_thread_manager(void *ctx_) /* Spawn threads... */ for (int ti = 0; ti < u->threads; ti++) { - struct spawn_ctx *ctx = malloc(sizeof(*ctx)); + struct spawn_ctx *ctx = malloc2(sizeof(*ctx)); ctx->u = u; ctx->b = mctx->b; ctx->color = mctx->color; mctx->t = ctx->t = shared_tree ? t : tree_copy(t); ctx->tid = ti; ctx->seed = fast_random(65536) + ti; @@ -755,7 +755,7 @@ uct_pondering_start(struct uct *u, struct board *b0, struct tree *t, enum stone u->pondering = true; /* We need a local board copy to ponder upon. */ - struct board *b = malloc(sizeof(*b)); board_copy(b, b0); + struct board *b = malloc2(sizeof(*b)); board_copy(b, b0); /* *b0 did not have the genmove'd move played yet. */ struct move m = { t->root->coord, t->root_color }; @@ -1088,7 +1088,7 @@ uct_dumpbook(struct engine *e, struct board *b, enum stone color) struct uct * uct_state_init(char *arg, struct board *b) { - struct uct *u = calloc(1, sizeof(struct uct)); + struct uct *u = calloc2(1, sizeof(struct uct)); bool using_elo = false; u->debug_level = debug_level; @@ -1420,8 +1420,8 @@ uct_state_init(char *arg, struct board *b) u->playout = playout_moggy_init(NULL, b); u->playout->debug_level = u->debug_level; - u->ownermap.map = malloc(board_size2(b) * sizeof(u->ownermap.map[0])); - u->stats = malloc(board_size2(b) * sizeof(u->stats[0])); + u->ownermap.map = malloc2(board_size2(b) * sizeof(u->ownermap.map[0])); + u->stats = malloc2(board_size2(b) * sizeof(u->stats[0])); if (!u->dynkomi) u->dynkomi = uct_dynkomi_init_linear(u, NULL, b); @@ -1439,7 +1439,7 @@ struct engine * engine_uct_init(char *arg, struct board *b) { struct uct *u = uct_state_init(arg, b); - struct engine *e = calloc(1, sizeof(struct engine)); + struct engine *e = calloc2(1, sizeof(struct engine)); e->name = "UCT Engine"; e->printhook = uct_printhook_ownermap; e->notify_play = uct_notify_play; @@ -1456,7 +1456,7 @@ engine_uct_init(char *arg, struct board *b) "if I think I win, I play until you pass. " "Anyone can send me 'winrate' in private chat to get my assessment of the position."; if (!u->banner) u->banner = ""; - e->comment = malloc(sizeof(banner) + strlen(u->banner) + 1); + e->comment = malloc2(sizeof(banner) + strlen(u->banner) + 1); sprintf(e->comment, "%s %s", banner, u->banner); return e; diff --git a/uct/walk.c b/uct/walk.c index 95e6527..3fbed68 100644 --- a/uct/walk.c +++ b/uct/walk.c @@ -274,8 +274,8 @@ uct_playout(struct uct *u, struct board *b, enum stone player_color, struct tree struct playout_amafmap *amaf = NULL; if (u->policy->wants_amaf) { - amaf = calloc(1, sizeof(*amaf)); - amaf->map = calloc(board_size2(&b2) + 1, sizeof(*amaf->map)); + amaf = calloc2(1, sizeof(*amaf)); + amaf->map = calloc2(board_size2(&b2) + 1, sizeof(*amaf->map)); amaf->map++; // -1 is pass } diff --git a/util.h b/util.h index 742fea8..763e4a4 100644 --- a/util.h +++ b/util.h @@ -1,9 +1,38 @@ #ifndef ZZGO_UTIL_H #define ZZGO_UTIL_H +#include + /* Misc. definitions. */ #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect((x), 0) +static inline void * +checked_malloc(size_t size, char *filename, unsigned int line, const char *func) +{ + void *p = malloc(size); + if (!p) { + fprintf(stderr, "%s:%u: %s: OUT OF MEMORY malloc(%lu)\n", + filename, line, func, size); + exit(1); + } + return p; +} + +static inline void * +checked_calloc(size_t nmemb, size_t size, char *filename, unsigned int line, const char *func) +{ + void *p = calloc(nmemb, size); + if (!p) { + fprintf(stderr, "%s:%u: %s: OUT OF MEMORY calloc(%lu, %lu)\n", + filename, line, func, nmemb, size); + exit(1); + } + return p; +} + +#define malloc2(size) checked_malloc((size), __FILE__, __LINE__, __func__) +#define calloc2(nmemb, size) checked_calloc((nmemb), (size), __FILE__, __LINE__, __func__) + #endif -- 2.11.4.GIT