void * _typecheck_realloc(void * ptr, size_t size) { void * newmem; size_t oldsiz; if(ptr == 0) /* behaves like malloc */ return _typecheck_malloc(size); if(size == 0){ /* behaves like free */ _typecheck_free(ptr); return 0; } oldsiz = mhash_remove(ptr); newmem = realloc(ptr, size + TC_MALLOC_PADDING); if(newmem){ mhash_insert(newmem, size); if(newmem == ptr){ /* memory block extended */ if(size < oldsiz){ /* shrink */ _tcptr_clearTags((char *)ptr+size, oldsiz-size); } else { /* extend */ _tcptr_setTags((char *)ptr+oldsiz, size-oldsiz); } } else { /* new memory block created */ /*NOTE: newmem and old block may overlap: must clear before set!! */ _tcptr_clearTags(ptr, oldsiz); _tcptr_setTags(newmem, size); } } return newmem; }
/* don't output error if ptr target not allocated */ void _typecheck_free_partial(void * ptr) { size_t siz = mhash_remove(ptr); if(siz){ free(ptr); _tcptr_clearTags(ptr, siz); } }
bool mhash_removef(MHASH *table, const char *fmt, ...) { char key[1024]; va_list ap; va_start(ap, fmt); vsnprintf(key, sizeof(key), fmt, ap); va_end(ap); return mhash_remove(table, key); }
void _typecheck_free(void * ptr) { size_t siz = mhash_remove(ptr); if(siz){ free(ptr); _tcptr_clearTags(ptr, siz); } else { _output_flce(__FILE__,__LINE__,0,"(_typecheck_free)","Freeing unallocated memory"); } }
void test_basic() { MHASH *table; char s[KEY_LEN + 1], *ps[NODE_NUM], *data; MERR *err; for (int i = 0; i < NODE_NUM; i++) { //mstr_rand_string(s, KEY_LEN); snprintf(s, sizeof(s), "str %d", i); ps[i] = strdup(s); } err = mhash_init(&table, mhash_str_hash, mhash_str_comp, NULL); MTEST_ASSERT(err == MERR_OK); for (int i = 0; i < NODE_NUM; i++) { err = mhash_insert(table, ps[i], ps[i]); MTEST_ASSERT(err == MERR_OK); } MTEST_ASSERT(mhash_length(table) == NODE_NUM); for (int i = 0; i < NODE_NUM; i++) { MTEST_ASSERT(mhash_has_key(table, ps[i])); } for (int i = 0; i < NODE_NUM; i++) { data = mhash_lookup(table, ps[i]); MTEST_ASSERT(data == ps[i]); } for (int i = 0; i < NODE_NUM; i++) { MTEST_ASSERT(mhash_remove(table, ps[i])); } MTEST_ASSERT(mhash_length(table) == 0); mhash_destroy(&table); }