//Emulation heap calloc function unsigned int EmuHeap::calloc(unsigned int nmemb, unsigned int size) { //first malloc the block unsigned int addr = this->malloc(nmemb * size); if (addr != HEAP_ERROR) { //find the newly malloc'ed block and zeroize it MallocNode *node = findMallocNode(addr); //this should never fail memset(node->block, 0, node->size); } return addr; }
//emulations heap realloc function unsigned int EmuHeap::realloc(unsigned int ptr, unsigned int size) { unsigned int result = HEAP_ERROR; if (ptr == 0) { //act like malloc is ptr is NULL result = this->malloc(size); } else { //find the malloc'ed node MallocNode *node = findMallocNode(ptr); //round the new size to a word boundary size = (size + 3) & 0xFFFFFFFC; if (node) { if (size == node->size) { //no change in size? do nothing result = ptr; } else if (size < node->size) { //node shrinking, shrink node size and realloc its block node->size = size; node->block = (unsigned char*) ::realloc(node->block, size); result = ptr; } else { //node growing, allocate new block result = this->malloc(size); if (result != HEAP_ERROR) { //find the newly allocated node MallocNode *newnode = findMallocNode(result); //copy the old block into the new larger block memcpy(newnode->block, node->block, node->size); //free the old block this->free(ptr); } } } } return result; }
//emulations heap realloc function unsigned int EmuHeap::realloc(unsigned int ptr, unsigned int size) { unsigned int result = HEAP_ERROR; if (ptr == 0) { //act like malloc if ptr is NULL result = this->malloc(size); } else { //find the malloc'ed node MallocNode *node = findMallocNode(ptr); //round the new size to a word boundary size = (size + 3) & 0xFFFFFFFC; if (node) { if (size == node->size) { //no change in size? do nothing result = ptr; } else if (size < node->size) { //node shrinking, shrink node size node->size = size; result = ptr; } else { //node growing, allocate new block result = this->malloc(size); if (result != HEAP_ERROR) { //copy the old block into the new larger block for (unsigned int i = 0; i < node->size; i++) { patch_byte(result + i, get_byte(ptr + i)); } //free the old block this->free(ptr); } } } } return result; }