/** * Free memory */ void free(void* pos) { uint32_t* block = reinterpret_cast<uint32_t*>(pos); block--; if (!is_allocated(next_block(block))) { uint32_t new_size = size_of_block(block) + 4 + size_of_block(next_block(block)); record(block, new_size, kFree); } else { record(block, size_of_block(block), kFree); } }
/** * Allocate memory */ void* alloc(uint32_t size) { // aligned 2 if (size & 0b1) size += 1; void* cur = mstart_; for (; cur != mend_; cur = next_block(cur)) { uint32_t block_size = size_of_block(cur); if (block_size >= size && !is_allocated(cur)) { void* remain = slice_block(cur, size); uint32_t remain_size = block_size - 4 - size; // 4 bytes is for header if (remain_size > 0) { record(cur, size, kAllocated); record(remain, remain_size, kFree); } else { record(cur, block_size, kAllocated); } return reinterpret_cast<uint8_t*>(cur) + 4; } } return nullptr; }
void* next_block(void* block) const { uint32_t p_value = reinterpret_cast<uint32_t>(block); p_value += size_of_block(block) + 4; return reinterpret_cast<void*>(p_value); }
int main(int argc, char**argv) { void *heapA; void *pointers[TESTSIZE]; xbt_init(&argc,argv); XBT_INFO("Allocating a new heap"); heapA = xbt_mheap_new(-1, ((char*)sbrk(0)) + BUFFSIZE); if (heapA == NULL) { perror("attach 1 failed"); fprintf(stderr, "bye\n"); exit(1); } XBT_INFO("HeapA allocated"); int i, size; for (i = 0; i < TESTSIZE; i++) { size = size_of_block(i); pointers[i] = mmalloc(heapA, size); XBT_INFO("%d bytes allocated with offset %tx", size, ((char*)pointers[i])-((char*)heapA)); } XBT_INFO("All blocks were correctly allocated. Free every second block"); for (i = 0; i < TESTSIZE; i+=2) { size = size_of_block(i); mfree(heapA,pointers[i]); } XBT_INFO("Memset every second block to zero (yeah, they are not currently allocated :)"); for (i = 0; i < TESTSIZE; i+=2) { size = size_of_block(i); memset(pointers[i],0, size); } XBT_INFO("Re-allocate every second block"); for (i = 0; i < TESTSIZE; i+=2) { size = size_of_block(i); pointers[i] = mmalloc(heapA, size); } XBT_INFO("free all blocks (each one twice, to check that double free are correctly catched)"); for (i = 0; i < TESTSIZE; i++) { xbt_ex_t e; int gotit = 1; mfree(heapA, pointers[i]); TRY { mfree(heapA, pointers[i]); gotit = 0; } CATCH(e) { xbt_ex_free(e); } if (!gotit) xbt_die("FAIL: A double-free went undetected (for size:%d)",size_of_block(i)); } XBT_INFO("free again all blocks (to really check that double free are correctly catched)"); for (i = 0; i < TESTSIZE; i++) { xbt_ex_t e; int gotit = 1; TRY { mfree(heapA, pointers[i]); gotit = 0; } CATCH(e) { xbt_ex_free(e); } if (!gotit) xbt_die("FAIL: A double-free went undetected (for size:%d)",size_of_block(i)); } XBT_INFO("Damnit, I cannot break mmalloc this time. That's SO disappointing."); return 0; }