Commit 646ceae0 authored by Vadapalli K Chaitanya's avatar Vadapalli K Chaitanya

Update mm2.c

parent 274a4464
/* /*
* mm-naive.c - The fastest, least memory-efficient malloc package. * mm-naive.c - The fastest, least memory-efficient malloc package.
* *
* In this naive approach, a block is allocated by simply incrementing * In this naive approach, a block is allocated by simply incrementing
* the brk pointer. A block is pure payload. There are no headers or * the brk pointer. A block is pure payload. There are no headers or
* footers. Blocks are never coalesced or reused. Realloc is * footers. Blocks are never coalesced or reused. Realloc is
...@@ -35,6 +35,66 @@ team_t team = { ...@@ -35,6 +35,66 @@ team_t team = {
"member_2@cse.iitb.ac.in" "member_2@cse.iitb.ac.in"
}; };
typedef struct tree_node_
{
struct tree_node_ *left_node;
struct tree_node_ *right_node;
struct tree_node_ *parent_node;
}tree_node_t;
typedef enum
{
MM_FALSE,
MM_TRUE
} vm_bool_t;
typedef struct block_meta_data_
{
vm_bool_t is_free;
uint32_t block_size;
struct block_meta_data_ *prev_block;
struct block_meta_data_ *next_block;
tree_node_t tree_node;
} block_meta_data_t;
typedef struct block_end_meta_data_
{
uint32_t block_size;
} block_end_meta_data_t;
#define NEXT_META_BLOCK_BY_SIZE(block_meta_data_ptr) \
(block_meta_data_t *)((char *)(block_meta_data_ptr+1) \
+ block_meta_data_ptr->block_size \
+sizeof(block_end_meta_data_t))
#define mm_bind_blocks_for_allocation(allocated_meta_block,free_meta_block) \
free_meta_block->prev_block=allocated_meta_block; \
free_meta_block->next_block=allocated_meta_block->next_block; \
allocated_meta_block->next_block=free_meta_block; \
if(free_meta_block->next_block) \
free_meta_block->next_block->prev_block=free_meta_block
#define offsetof(struct_name,field_name) \
(unsigned int)&((struct_name *)0)->field_name
#define meta_data_block_addr(free_node_addr) \
(block_meta_data_t *) ((char *)(free_node_addr)-offsetof(block_meta_data_t,tree_node))
#define end_meta_data_addr(meta_data_addr) \
(block_end_meta_data_t *)((char *)(meta_data_addr+1) \
+meta_data_addr->block_size)
#define start_meta_data_addr(end_meta_data_addr) \
(block_meta_data_t *)((char *)(end_meta_data_addr) \
-end_meta_data_addr->block_size \
-sizeof(block_meta_data_t))
/* single word (4) or double word (8) alignment */ /* single word (4) or double word (8) alignment */
#define ALIGNMENT 8 #define ALIGNMENT 8
...@@ -44,36 +104,615 @@ team_t team = { ...@@ -44,36 +104,615 @@ team_t team = {
#define SIZE_T_SIZE (ALIGN(sizeof(size_t))) #define SIZE_T_SIZE (ALIGN(sizeof(size_t)))
/* /*
* mm_init - initialize the malloc package. * mm_init - initialize the malloc package.
*/ */
tree_node_t init_free_node(void)
{
tree_node_t treenode;
treenode.left_node=NULL;
treenode.right_node=NULL;
treenode.parent_node=NULL;
return treenode;
}
void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node);
void *init_mem_sbrk_break = NULL; void *init_mem_sbrk_break = NULL;
tree_node_t **root=NULL;
void LL_rotate(tree_node_t *parent,tree_node_t *node)
{
printf("Came to LL\n");
tree_node_t *p_parent=parent->parent_node;
tree_node_t *temp=parent->left_node;
tree_node_t *temp_right=temp->right_node;
if(p_parent==NULL)
{
*root=temp;
temp->parent_node=NULL;
}
else
{
block_meta_data_t *p_parent_meta_data=meta_data_block_addr(p_parent);
block_meta_data_t *temp_meta_data=meta_data_block_addr(temp);
temp->parent_node=p_parent;
if(temp_meta_data->block_size<=p_parent_meta_data->block_size)
{
p_parent->left_node=temp;
}
else
{
p_parent->right_node=temp;
}
}
temp->right_node=parent;
parent->parent_node=temp;
parent->left_node=temp_right;
}
void LR_Rotate(tree_node_t *parent,tree_node_t *node)
{
printf("Came to LR\n");
tree_node_t *p_parent=parent->parent_node;
tree_node_t *temp=parent->left_node;
block_meta_data_t *meta_data=meta_data_block_addr(temp);
tree_node_t *node_left=node->left_node;
tree_node_t *node_right=node->right_node;
if(p_parent==NULL)
{
*root=node;
node->parent_node=NULL;
}
else
{
block_meta_data_t *p_parent_meta_data=meta_data_block_addr(p_parent);
block_meta_data_t *node_meta_data=meta_data_block_addr(node);
node->parent_node=p_parent;
if(node_meta_data->block_size<=p_parent_meta_data->block_size)
{
p_parent->left_node=node;
}
else
{
p_parent->right_node=node;
}
}
node->right_node=parent;
parent->parent_node=node;
node->left_node=temp;
temp->parent_node=node;
parent->left_node=node_right;
temp->right_node=node_left;
}
void RR_Rotate(tree_node_t *parent,tree_node_t *node)
{
printf("Came to RR\n");
tree_node_t *p_parent=parent->parent_node;
tree_node_t *temp=parent->right_node;
tree_node_t *temp_left=temp->left_node;
if(p_parent==NULL)
{
*root=temp;
temp->parent_node=NULL;
}
else
{
temp->parent_node=p_parent;
block_meta_data_t *p_parent_meta_data=meta_data_block_addr(p_parent);
block_meta_data_t *temp_meta_data=meta_data_block_addr(temp);
if(temp_meta_data->block_size<=p_parent_meta_data->block_size)
{
p_parent->left_node=temp;
}
else
{
p_parent->right_node=temp;
}
temp->left_node=parent;
parent->parent_node=temp;
parent->right_node=temp_left;
}
}
void RL_Rotate(tree_node_t *parent,tree_node_t *node)
{
printf("Came to RL\n");
tree_node_t *p_parent=parent->parent_node;
tree_node_t *temp=parent->right_node;
tree_node_t *temp_right=temp->right_node;
tree_node_t *node_left=node->left_node;
tree_node_t *node_right=node->right_node;
if(p_parent==NULL)
{
*root=node;
node->parent_node=NULL;
}
else
{
node->parent_node=p_parent;
block_meta_data_t *p_parent_meta_data=meta_data_block_addr(p_parent);
block_meta_data_t *node_meta_data=meta_data_block_addr(node);
if(node_meta_data->block_size<=p_parent_meta_data->block_size)
{
p_parent->left_node=node;
}
else
{
p_parent->right_node=node;
}
}
node->left_node=parent;
parent->parent_node=node;
node->right_node=temp;
temp->parent_node=node;
parent->right_node=node_right;
temp->left_node=node_left;
}
void rotate(tree_node_t *parent,tree_node_t *node)
{
block_meta_data_t *parent_meta_data=meta_data_block_addr(parent);
block_meta_data_t *node_meta_data=meta_data_block_addr(node);
if(parent_meta_data->block_size<node_meta_data->block_size)
{
tree_node_t *temp=parent->right_node;
block_meta_data_t *temp_meta_data=meta_data_block_addr(temp);
if(temp_meta_data->block_size<node_meta_data->block_size)
{
RR_Rotate(parent,node);
}
else
{
RL_Rotate(parent,node);
}
}
else
{
tree_node_t *temp=parent->left_node;
block_meta_data_t *temp_meta_data=meta_data_block_addr(temp);
if(temp_meta_data->block_size<node_meta_data->block_size)
{
inorderTraversal(*root);
LR_Rotate(parent,node);
}
else
{
LL_rotate(parent,node);
}
}
}
int getHeight(tree_node_t *node)
{
if(node==NULL)
{
return 0;
}
int left_height=getHeight(node->left_node);
int right_height=getHeight(node->right_node);
return 1+(left_height>=right_height?left_height:right_height);
}
int get_balance(tree_node_t *node)
{
if(node!=NULL)
{
inorderTraversal(*root);
int left_height=getHeight(node->left_node);
int right_height=getHeight(node->right_node);
return (left_height-right_height);
}
return 0;
}
void inorderTraversal(tree_node_t *node)
{
if(node!=NULL)
{
block_meta_data_t *meta_data_block=meta_data_block_addr(node);
printf("Block size=%d\n",(int)meta_data_block->block_size);
inorderTraversal(node->left_node);
inorderTraversal(node->right_node);
}
}
void insert_node_in_freelist(tree_node_t **root,block_meta_data_t *new_metadata_block)
{
tree_node_t *tree_root=*root;
if(tree_root==NULL)
{
*root=&(new_metadata_block->tree_node);
}
else
{
tree_node_t *temp=tree_root;
while(temp)
{
block_meta_data_t *meta_data=meta_data_block_addr(temp);
if(new_metadata_block->block_size<=meta_data->block_size)
{
if(temp->left_node==NULL)
{
new_metadata_block->tree_node.parent_node=temp;
temp->left_node=&(new_metadata_block->tree_node);
temp=temp->left_node;
break;
}
else
{
temp=temp->left_node;
}
}
else if(new_metadata_block->block_size>meta_data->block_size)
{
if(temp->right_node==NULL)
{
new_metadata_block->tree_node.parent_node=temp;
temp->right_node=&(new_metadata_block->tree_node);
temp=temp->right_node;
break;
}
else
{
temp=temp->right_node;
}
}
}
tree_node_t *parent=temp->parent_node;
while(parent)
{
int b=get_balance(parent);
if(b>=2||b<=-2)
{
rotate(parent,temp);
}
parent=parent->parent_node;
}
}
}
block_meta_data_t *get_node_from_tree(tree_node_t **root,uint32_t reqsize)
{
tree_node_t *temp=*root;
while(temp->right_node!=NULL)
{
temp=temp->right_node;
}
block_meta_data_t *meta_data=NULL;
meta_data=meta_data_block_addr(temp);
return meta_data;
}
tree_node_t *get_min_node(tree_node_t *root)
{
tree_node_t *temp=root;
while(temp->left_node!=NULL)
{
temp=temp->left_node;
}
return temp;
}
void remove_block_from_tree(tree_node_t **root,tree_node_t *del_node)
{
tree_node_t *parent_node=del_node->parent_node;
block_meta_data_t *parent_meta_data=meta_data_block_addr(parent_node);
block_meta_data_t *del_meta_data=meta_data_block_addr(del_node);
if(del_node->left_node==NULL||del_node->right_node==NULL)
{
tree_node_t *temp=del_node->left_node!=NULL?del_node->left_node:del_node->right_node;
//Deleting a leaf node
if(temp==NULL)
{
if(parent_node==NULL)
{
*root=NULL;
return;
}
if(parent_meta_data->block_size<del_meta_data->block_size)
{
parent_node->right_node=NULL;
}
else
{
parent_node->left_node=NULL;
}
}
//Deleting node having 1 child
else
{
if(del_node->left_node!=NULL)
{
del_node->left_node->parent_node=parent_node;
if(parent_node==NULL)
{
*root=del_node->left_node;
del_node->left_node=NULL;
del_node->right_node=NULL;
del_node->parent_node=NULL;
return;
}
else if(parent_meta_data->block_size<del_meta_data->block_size)
{
parent_node->right_node=del_node->left_node;
}
else
{
parent_node->left_node=del_node->left_node;
}
}
else
{
del_node->right_node->parent_node=parent_node;
if(parent_node==NULL)
{
*root=del_node->right_node;
del_node->left_node=NULL;
del_node->right_node=NULL;
del_node->parent_node=NULL;
return;
}
else if(parent_meta_data->block_size<del_meta_data->block_size)
{
parent_node->right_node=del_node->right_node;
}
else
{
parent_node->left_node=del_node->right_node;
}
}
}
//Balancing parent node
while(parent_node)
{
int b=get_balance(parent_node);
if(b<-1)
{
if(parent_node->right_node->right_node!=NULL)
{
RR_Rotate(parent_node,parent_node->right_node->right_node);
}
else
{
RL_Rotate(parent_node,parent_node->right_node->left_node);
}
}
if(b>1)
{
if(parent_node->left_node->left_node!=NULL)
{
LL_rotate(parent_node,parent_node->left_node->left_node);
}
else
{
LR_Rotate(parent_node,parent_node->left_node->right_node);
}
}
parent_node=parent_node->parent_node;
}
}
//Deleting node having two children
else
{
tree_node_t *min_right_node=get_min_node(del_node->right_node);
remove_block_from_tree(root,min_right_node);
tree_node_t *parent_node_1=del_node->parent_node;
block_meta_data_t *parent_meta_data_1=meta_data_block_addr(parent_node_1);
if(parent_node_1==NULL)
{
*root=min_right_node;
}
else if(parent_meta_data_1->block_size<del_meta_data->block_size)
{
parent_node_1->right_node=min_right_node;
}
else
{
parent_node_1->left_node=min_right_node;
}
min_right_node->left_node=del_node->left_node;
if(del_node->left_node!=NULL)
{
del_node->left_node->parent_node=min_right_node;
}
min_right_node->right_node=del_node->right_node;
if(del_node->right_node!=NULL)
{
del_node->right_node->parent_node=min_right_node;
}
min_right_node->parent_node=parent_node_1;
}
del_node->left_node=NULL;
del_node->right_node=NULL;
del_node->parent_node=NULL;
}
int get_internal_fragmented_size(block_meta_data_t *block1,block_meta_data_t *block2)
{
block_meta_data_t *next_meta_block_by_size=NEXT_META_BLOCK_BY_SIZE(block1);
return (int)((char *)block2-(char *)next_meta_block_by_size);
}
void merge_free_blocks(block_meta_data_t *first,block_meta_data_t *second)
{
assert(first->is_free==MM_TRUE&&second->is_free==MM_TRUE);
first->block_size+=sizeof(block_meta_data_t) + second->block_size+sizeof(block_end_meta_data_t);
first->next_block=second->next_block;
if(second->next_block!=NULL)
{
second->next_block->prev_block=first;
}
}
int mm_init(void) int mm_init(void)
{ {
//This function is called every time before each test run of the trace. //This function is called every time before each test run of the trace.
//It should reset the entire state of your malloc or the consecutive trace runs will give wrong answer. //It should reset the entire state of your malloc or the consecutive trace runs will give wrong answer.
/*
/*
* This function should initialize and reset any data structures used to represent the starting state(empty heap) * This function should initialize and reset any data structures used to represent the starting state(empty heap)
* *
* This function will be called multiple time in the driver code "mdriver.c" * This function will be called multiple time in the driver code "mdriver.c"
*/ */
if(init_mem_sbrk_break==NULL)
{
mem_init();
}
mem_reset_brk();
init_mem_sbrk_break=mem_sbrk(mem_pagesize());
if(*(int *)init_mem_sbrk_break==-1)
{
return -1;
}
root=(tree_node_t **)init_mem_sbrk_break;
block_meta_data_t *metadata=(block_meta_data_t *)(root+1);
metadata->is_free=MM_TRUE;
metadata->block_size=mem_pagesize()-sizeof(block_meta_data_t)-sizeof(block_end_meta_data_t)-sizeof(root);
metadata->tree_node=init_free_node();
metadata->next_block=NULL;
metadata->prev_block=NULL;
*root=&(metadata->tree_node);
block_end_meta_data_t *end_meta_data=end_meta_data_addr(metadata);
end_meta_data->block_size=metadata->block_size;
return 0; //Returns 0 on successfull initialization. return 0; //Returns 0 on successfull initialization.
} }
//--------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------
/* /*
* mm_malloc - Allocate a block by incrementing the brk pointer. * mm_malloc - Allocate a block by incrementing the brk pointer.
* Always allocate a block whose size is a multiple of the alignment. * Always allocate a block whose size is a multiple of the alignment.
*/ */
void *mm_malloc(size_t size) void *mm_malloc(size_t size)
{ {
/* /*
* This function should keep track of the allocated memory blocks. * This function should keep track of the allocated memory blocks.
* The block allocation should minimize the number of holes (chucks of unusable memory) in the heap memory. * The block allocation should minimize the number of holes (chucks of unusable memory) in the heap memory.
* The previously freed memory blocks should be reused. * The previously freed memory blocks should be reused.
...@@ -85,38 +724,201 @@ void *mm_malloc(size_t size) ...@@ -85,38 +724,201 @@ void *mm_malloc(size_t size)
return NULL; return NULL;
} }
size = ((size+7)/8)*8; //size alligned to 8 bytes size = ((size+7)/8)*8; //size alligned to 8 bytes
return mem_sbrk(size); //mem_sbrk() is wrapper function for the sbrk() system call. block_meta_data_t *free_metadata_block=get_node_from_tree(root,size);
//Please use mem_sbrk() instead of sbrk() otherwise the evaluation results
//may give wrong results //If No free block available then we will request new pages by calling mem_sbrk()
if(free_metadata_block==NULL||free_metadata_block->block_size<(size+sizeof(block_end_meta_data_t)+sizeof(block_meta_data_t)))
{
size_t sys_page_size=mem_pagesize();
int no_of_pages_req=((size+sizeof(block_end_meta_data_t)+sizeof(block_meta_data_t)+sys_page_size-1)/sys_page_size);
size_t extra_size_req=(int)no_of_pages_req*sys_page_size;
void *brk= mem_sbrk(extra_size_req);
if(*(int *)brk==-1)
{
return NULL;
}
block_end_meta_data_t *prev_end_meta_data=NULL;
prev_end_meta_data=(block_end_meta_data_t *)((char *)brk-sizeof(block_end_meta_data_t));
block_meta_data_t *prev_start_meta_data=NULL;
prev_start_meta_data=start_meta_data_addr(prev_end_meta_data);
block_meta_data_t *next_meta_data_block=(block_meta_data_t *)brk;
next_meta_data_block->is_free=MM_FALSE;
next_meta_data_block->block_size=size;
next_meta_data_block->tree_node=init_free_node();
next_meta_data_block->prev_block=prev_start_meta_data;
prev_start_meta_data->next_block=next_meta_data_block;
next_meta_data_block->next_block=NULL;
block_end_meta_data_t *next_end_meta_data_block=end_meta_data_addr(next_meta_data_block);
next_end_meta_data_block->block_size=next_meta_data_block->block_size;
block_meta_data_t *new_free_meta_block=NEXT_META_BLOCK_BY_SIZE(next_meta_data_block);
new_free_meta_block->is_free=MM_TRUE;
new_free_meta_block->block_size=(uint32_t)(extra_size_req-size-(2*sizeof(block_meta_data_t))-(2*sizeof(block_end_meta_data_t)));
new_free_meta_block->tree_node=init_free_node();
new_free_meta_block->prev_block=NULL;
block_end_meta_data_t *new_end_free_meta_block=end_meta_data_addr(new_free_meta_block);
new_end_free_meta_block->block_size=new_free_meta_block->block_size;
insert_node_in_freelist(root,new_free_meta_block);
mm_bind_blocks_for_allocation(next_meta_data_block,new_free_meta_block);
return (void *)(next_meta_data_block+1);
}
assert(free_metadata_block->is_free==MM_TRUE);
printf("Free Data block size=%d\n",(int)free_metadata_block->block_size);
uint32_t remaining_size=free_metadata_block->block_size-size;
free_metadata_block->is_free=MM_FALSE;
free_metadata_block->block_size=size;
block_end_meta_data_t *end_meta_data=end_meta_data_addr(free_metadata_block);
end_meta_data->block_size=size;
remove_block_from_tree(root,&free_metadata_block->tree_node);
//Here we will created new block by splitting previous block
if(sizeof(block_meta_data_t)+sizeof(block_end_meta_data_t)<remaining_size){
block_meta_data_t *next_meta_block=NULL;
block_end_meta_data_t *next_end_meta_block=NULL;
next_meta_block=NEXT_META_BLOCK_BY_SIZE(free_metadata_block);
next_meta_block->is_free=MM_TRUE;
next_meta_block->block_size=remaining_size-sizeof(block_meta_data_t)-sizeof(block_end_meta_data_t);
next_meta_block->tree_node=init_free_node();
next_end_meta_block=end_meta_data_addr(next_meta_block);
next_end_meta_block->block_size=next_meta_block->block_size;
insert_node_in_freelist(root,next_meta_block);
mm_bind_blocks_for_allocation(free_metadata_block,next_meta_block);
}
return (void *)(free_metadata_block+1);
//mem_sbrk() is wrapper function for the sbrk() system call.
//Please use mem_sbrk() instead of sbrk() otherwise the evaluation results
//may give wrong results
} }
void mm_free(void *ptr) void mm_free(void *ptr)
{ {
/* /*
* Searches the previously allocated node for memory block with base address ptr. * Searches the previously allocated node for memory block with base address ptr.
* *
* It should also perform coalesceing on both ends i.e. if the consecutive memory blocks are * It should also perform coalesceing on both ends i.e. if the consecutive memory blocks are
* free(not allocated) then they should be combined into a single block. * free(not allocated) then they should be combined into a single block.
* *
* It should also keep track of all the free memory blocks. * It should also keep track of all the free memory blocks.
* If the freed block is at the end of the heap then you can also decrease the heap size * If the freed block is at the end of the heap then you can also decrease the heap size
* using 'mem_sbrk(-size)'. * using 'mem_sbrk(-size)'.
*/ */
block_meta_data_t *meta_data_block=(block_meta_data_t *)((char *)ptr-sizeof(block_meta_data_t));
assert(meta_data_block->is_free==MM_FALSE);
meta_data_block->is_free=MM_TRUE;
block_meta_data_t *prev_meta_data_block=meta_data_block->prev_block;
block_meta_data_t *next_meta_data_block=meta_data_block->next_block;
block_meta_data_t *merged_meta_data_block=NULL;
block_end_meta_data_t *merged_end_meta_data_block=NULL;
if(next_meta_data_block!=NULL)
{
meta_data_block->block_size+= get_internal_fragmented_size(meta_data_block,next_meta_data_block);
}
//If block being free is upper most block
else
{
int fragmented_size=(int)((char *)mem_heap_hi()+1-((char *)end_meta_data_addr(meta_data_block)+sizeof(block_end_meta_data_t)));
meta_data_block->block_size+=fragmented_size;
}
merged_meta_data_block=meta_data_block;
if(next_meta_data_block!=NULL&&next_meta_data_block->is_free==MM_TRUE)
{
remove_block_from_tree(root,&next_meta_data_block->tree_node);
merge_free_blocks(meta_data_block,next_meta_data_block);
merged_meta_data_block=meta_data_block;
}
if(prev_meta_data_block!=NULL&&prev_meta_data_block->is_free==MM_TRUE)
{
remove_block_from_tree(root,&prev_meta_data_block->tree_node);
merge_free_blocks(prev_meta_data_block,meta_data_block);
merged_meta_data_block=prev_meta_data_block;
}
merged_end_meta_data_block=(block_end_meta_data_t *)(end_meta_data_addr(merged_meta_data_block));
merged_end_meta_data_block->block_size=merged_meta_data_block->block_size;
insert_node_in_freelist(root,merged_meta_data_block);
} }
/* /*
* mm_realloc - Implemented simply in terms of mm_malloc and mm_free * mm_realloc - Implemented simply in terms of mm_malloc and mm_free
*/ */
void *mm_realloc(void *ptr, size_t size) void *mm_realloc(void *ptr, size_t size)
{ {
size = ((size+7)/8)*8; //8-byte alignement size = ((size+7)/8)*8; //8-byte alignement
if(ptr == NULL){ //memory was not previously allocated if(ptr == NULL){ //memory was not previously allocated
return mm_malloc(size); return mm_malloc(size);
} }
if(size == 0){ //new size is zero if(size == 0){ //new size is zero
mm_free(ptr); mm_free(ptr);
return NULL; return NULL;
...@@ -125,14 +927,39 @@ void *mm_realloc(void *ptr, size_t size) ...@@ -125,14 +927,39 @@ void *mm_realloc(void *ptr, size_t size)
/* /*
* This function should also copy the content of the previous memory block into the new block. * This function should also copy the content of the previous memory block into the new block.
* You can use 'memcpy()' for this purpose. * You can use 'memcpy()' for this purpose.
* *
* The data structures corresponding to free memory blocks and allocated memory * The data structures corresponding to free memory blocks and allocated memory
* blocks should also be updated. * blocks should also be updated.
*/ */
mm_free(ptr); mm_free(ptr);
return mem_sbrk(size); return mem_sbrk(size);
}
int main()
{
mm_init();
void *p1=mm_malloc(40);
void *p2=mm_malloc(40);
void *p3=mm_malloc(60);
void *p4=mm_malloc(100);
void *p5=mm_malloc(20);
void *p6=mm_malloc(90);
void *p7=mm_malloc(3500);
printf("Above Call Executed\n");
mm_free(p2);
mm_free(p4);
mm_free(p6);
mm_free(p1);
mm_free(p3);
mm_free(p5);
inorderTraversal(*root);
//mm_free(p2);
//mm_free(p2);
//void *p4=mm_malloc(40);
return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment