-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctions.c
152 lines (127 loc) · 4.96 KB
/
functions.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
147
148
149
150
151
152
#include "./functions.h"
HEADER* headOfHeap = NULL;
/// @brief New malloc function. Allocate SIZE bytes of memory.
/// @param size Size to allocate.
/// @return Void pointer to the allocated space, or NULL if there is insufficient memory available.
void *malloc_3is(size_t size)
{
HEADER* returnValue = NULL;
if (0 == size)
{
return returnValue;
}
HEADER* currentElement = headOfHeap;
HEADER* previousElement = NULL;
while(NULL != currentElement)
{
// If the size is the same size as a element that has been free, use the given block.
if (currentElement->bloc_size == size)
{
if (headOfHeap == currentElement)
{
headOfHeap = headOfHeap->ptr_next;
}
else
{
previousElement->ptr_next = currentElement->ptr_next;
}
currentElement->ptr_next = NULL;
returnValue = currentElement;
break;
}
// If the bloc can be split in two for this one and another one for the futur, do it
if (currentElement->bloc_size > (size + sizeof(HEADER) + 1 + sizeof(MAGIC_NUMBER)))
{
// Create a new block for the remaining free space
HEADER *newBlock = (HEADER*)((void*)currentElement + size + sizeof(HEADER) + sizeof(MAGIC_NUMBER));
newBlock->bloc_size = currentElement->bloc_size - (size + sizeof(HEADER) + sizeof(MAGIC_NUMBER));
newBlock->magic_number = MAGIC_NUMBER;
//Write a new magic number to end the turned block early
//The new block will keep the previous magic number
long* adressOfMagicNumber = (void*) (currentElement) + size + sizeof(HEADER);
*adressOfMagicNumber = MAGIC_NUMBER;
//Put the new bloc in the Linked List and remove the returned one
if (headOfHeap == currentElement)
{
newBlock->ptr_next = headOfHeap->ptr_next;
headOfHeap = newBlock;
}
else
{
newBlock->ptr_next = currentElement->ptr_next;
previousElement->ptr_next = newBlock;
}
//Update Returned block header
currentElement->bloc_size = size;
currentElement->ptr_next = NULL;
returnValue = currentElement;
break;
}
previousElement = currentElement;
currentElement = currentElement->ptr_next;
}
if (NULL == currentElement)
{
HEADER* currentStateOfHeap = sbrk(sizeof(HEADER) + size + sizeof(long));
currentStateOfHeap->ptr_next = NULL;
currentStateOfHeap->bloc_size = size;
currentStateOfHeap->magic_number = MAGIC_NUMBER;
long* adressOfTail = (void*) (currentStateOfHeap) + size + sizeof(HEADER);
*adressOfTail = MAGIC_NUMBER;
returnValue = currentStateOfHeap;
}
return returnValue + 1;
}
/// @brief New free function. Free a block allocated by 'malloc'.
/// @param ptr Pointer to de-allocate.
void free_3is(void *ptr)
{
HEADER* blockToFree = ((HEADER*)ptr) - 1;
// If the list is empty or the block to free should be inserted at the beginning
if (headOfHeap == NULL || blockToFree < headOfHeap)
{
blockToFree->ptr_next = headOfHeap;
headOfHeap = blockToFree;
}
else
{
HEADER* current = headOfHeap;
HEADER* previous = NULL;
// Traverse the list to find the correct position to insert the block
while (current != NULL && current < blockToFree)
{
previous = current;
current = current->ptr_next;
}
//Check if the previous block is adjacent to the freed one to fuse them
linkBlocks(blockToFree,current);
linkBlocks(previous,blockToFree);
}
}
/// @brief Try to fuse the two block, else link them in the linked list
/// @param ptr1 First Block ie (ptr1 < ptr2)
/// @param ptr2 Second Block
void linkBlocks(HEADER* ptr1, HEADER* ptr2){
//Check if the blocks are adjacents to fuse them
if((void*) ptr1+ptr1->bloc_size+sizeof(HEADER)+sizeof(MAGIC_NUMBER) == ptr2){
ptr1->bloc_size = ptr1->bloc_size + +sizeof(HEADER)+sizeof(MAGIC_NUMBER) +ptr2->bloc_size;
ptr1->ptr_next = ptr2->ptr_next;
}
//Else, just link them in the List
else{
ptr1->ptr_next = ptr2;
}
}
/// @brief Check if an adress as not been corrupted.
/// @param ptr Pointer to the element to check.
/// @return True if the adress was corrupted, false either.
bool checkIfAdressCorrect(void* ptr)
{
HEADER* nodeToCheck = (HEADER*) (ptr) - 1;
// Check the magic number in the header
bool firstCheck = (MAGIC_NUMBER == nodeToCheck->magic_number);
// Check the magic number at the tail of the structure.
long* adressOfTail = (long*) (ptr + nodeToCheck->bloc_size);
bool secondCheck = (MAGIC_NUMBER == *adressOfTail);
return firstCheck && secondCheck;
}