-
Notifications
You must be signed in to change notification settings - Fork 0
/
malloc.c
106 lines (85 loc) · 2.15 KB
/
malloc.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
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
struct __attribute__((__packed__)) __malloc_link
{
void* start;
void* next;
};
struct __malloc_link __MALLOC_GUARD = {NULL, NULL};
struct __malloc_link* __MALLOC_GLOBAL_HEAD = &__MALLOC_GUARD;
#ifdef DEBUG
void
print_linked_list(struct __malloc_link* head)
{
while (head)
{
fprintf(stdout, "\tnode[%p] = {start = %p; next %p}\n",
head, head->start, head->next);
head = head->next;
}
}
#endif
void*
malloc(size_t size)
{
struct __malloc_link* header;
void* candidate;
if (size == 0)
return NULL;
#ifdef DEBUG
fprintf(stdout, "+ malloc %zu bytes requested.\n", size);
fprintf(stdout, "\tcurrent sbrk: %p\n", sbrk(0));
#endif
candidate = sbrk(size + sizeof(struct __malloc_link));
/* failed */
if (candidate < 0)
return candidate;
/* setup header */
header = (struct __malloc_link*) candidate;
header->start = candidate + sizeof(struct __malloc_link);
/* refresh head of list */
header->next = __MALLOC_GLOBAL_HEAD;
__MALLOC_GLOBAL_HEAD = header;
#ifdef DEBUG
print_linked_list(__MALLOC_GLOBAL_HEAD);
#endif
return header->start;
}
void
free(void* pointer)
{
struct __malloc_link* prev = __MALLOC_GLOBAL_HEAD;
struct __malloc_link* current = __MALLOC_GLOBAL_HEAD;
#ifdef DEBUG
fprintf(stdout, "+ free address 0x%p\n", pointer);
#endif
while (current && (current->start != pointer))
{
prev = current;
current = current->next;
#ifdef DEBUG
fprintf(stdout, "\twhile loop, checking current->next == %p\n",
current->next);
#endif
}
#ifdef DEBUG
fprintf(stdout, "\tmatched: start = %p, pointer = %p\n", current->start,
pointer);
#endif
if (current && current->start)
{
/* remove from linked list */
if (current == __MALLOC_GLOBAL_HEAD)
{
__MALLOC_GLOBAL_HEAD = current->next;
brk(current);
}
else
prev->next = current->next;
}
#ifdef DEBUG
print_linked_list(__MALLOC_GLOBAL_HEAD);
#endif
return;
}