void * mm_realloc(void *bp, size_t newsize) param: bp - A pointer to an allocated block (that may already have user data in the payload) param: newsize - A new size requested Description: Special cases: (1) if newsize is 0, call mm_free(bp) and return NULL (2) if bp is NULL, call and return mm_malloc(bp) Otherwise: Return a block of size >= newsize that preserves all the data from the payload of the block bp. Suggested Optimizations: (1) If newsize <= current size of bp, just return bp (2) If the next block after bp is free and its size plus the size of bp is >= the requested newsize, remove the free block, rewrite the header and then the footer of bp to change the size of bp and return bp. (3) If the next block after bp is free, but its size plus the size of bp is NOT >= the requested newsize, BUT this next block is the 'last' block (before the epilog), call extend_heap to get additional size and rewrite the header and then the footer of bp to change the size of bp. Return bp. (4) If bp is the 'last' block (before the epilog), call extend_heap to get additional size and rewrite the header and then the footer of bp to change the size of bp. Return bp. If none of these optimizations apply, use mm_malloc to get a new block, the C library function memcpy to copy the payload to the new block, mm_free block to free bp and return the new block. Return: A pointer to the new sized block (with the preserved data) or NULL if no such block could be produced.