-
Notifications
You must be signed in to change notification settings - Fork 0
/
mymalloc.c
146 lines (132 loc) · 4.13 KB
/
mymalloc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <stdio.h>
#include <stddef.h>
#include "mymalloc.h"
void * mymalloc(size_t min_size){
if(min_size >= SIZE){
printf("error1: Tried to allocate memory larger than or equal to the entire memory block\n");
return NULL;
}
// creating two pointers to use (curr and last) during the progress of mymalloc
struct meta *curr,*last;
void *pointer;
// if the size of the first metadata is zero, then...
if((initList->size)==0){
// we have not initialized the array. Let's do that now
init();
// done!
}
// this is our current block (the init meta block)
curr = initList;
// checking the metadata one by one until we reach a block that can fit or we reach NULL (no next meta block).
while(((curr->next != NULL) && (((curr->empty) == 0) || ((curr->size) < (min_size + sizeof(struct meta)))))){
// set the last mata to the current one (temp)
last = curr;
// set the curr meta to the next one (or NULL)
curr = (curr->next);
}
// if there is a block with the exact amount of space needed for the allocation
if((curr->size) == min_size){
// curr is now in use
curr->empty = 0;
//
pointer = (void*)(++curr);
// return the pointer to the metadata of the allocated memory
return pointer;
}
// if there is a block available with more than enough space for the allocation
else if((curr->size) > (min_size + sizeof(struct meta))){
// segmenting the large memory block
segment(curr, min_size);
//
pointer = (void*)(++curr);
// return the pointer to the metadata of the allocated memory
return pointer;
}
// if there is no block with suficient memory
else{
pointer = NULL;
printf("error0: There was no memory to allocate\n");
// return a null pointer
return pointer;
}
}
void myfree(void* pointer){
struct meta* x = (struct meta*)(((char*)pointer) - sizeof(struct meta));
if ((char*) x < memory || (char*) x >= memory + sizeof(memory)){
printf("%s\n", "error1");
return NULL;
}
else if(x->empty != 0){
printf("%s\n", "error2");
return NULL;
}
// check if the pointer leads to a valid memory location
// if it does,
// if((pointer <= (void*)(memory+SIZE)) && ((void*)memory<=pointer)){
else if(x->empty == 0){
// set the metadata to empty=1
struct meta *curr = pointer;
--curr;
curr->empty = 1;
// then defragment
defrag();
}
// else
else{
// print out an error message
printf("error2: You did not give a valid malloc pointer.\n");
}
}
/**
* This function will defragment the memory blocks.
*/
void defrag(){
// you know what this line means lol
struct meta *curr, *last;
// the current is equal to the start
curr = initList;
// while there is a next metadata and curr is not NULL...
while(curr != NULL && (curr->next) != NULL){
// if curr is empty (unallocated) and the next block is empty (unallocated)...
if((curr->empty != 0) && (curr->next->empty != 0)){
// set the current meta size to the size of the next block and it's metadata
curr->size += (curr->next->size) + sizeof(struct meta);
// the next meta in the current meta is set to the next meta in the next meta (does that even make sense? It does to me so lmao)
curr->next = curr->next->next;
}
// the last meta is now equal to the current meta
// the current meta is now equal to the next meta
last = curr;
curr = curr->next;
// these last two lines we are basically traversing the different metadatas in the linked list
}
// curr = initList;
// while (curr != NULL){
// printf("%d\n", curr->size);
// curr = curr->next;
// }
}
/**
* used to set the initial size of memory able to be used.
*/
void init(){
// initial metadata
initList->size=SIZE-sizeof(struct meta);
initList->empty=1;
initList->next=NULL;
}
/**
* Used to segment the given memory size
*/
void segment(struct meta *big_block, size_t size){
// init a new metadata block
struct meta *new = (void*)((void*)big_block + size + sizeof(struct meta));
// make the new metadata
new->size = (big_block->size) - size - sizeof(struct meta);
new->empty = 1;
new->next = big_block->next;
// allocate the given memory block define the next metadata in the link as the one created
big_block->size = size;
big_block->empty = 0;
big_block->next = new;
}