-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmemory_management.c
More file actions
148 lines (132 loc) · 2.99 KB
/
Copy pathmemory_management.c
File metadata and controls
148 lines (132 loc) · 2.99 KB
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
#include <stddef.h>
#include <stdio.h>
#include "memory_management.h"
void printFreeList()
{
printf("Free List: ");
struct Block *curr = freeList;
while (curr != NULL)
{
printf("[%zu] -> ", curr->size);
curr = curr->next;
}
printf("NULL\n");
}
// Global variable to keep track of the allocated memory blocks
void initialize()
{
freeList = (Block *)heap;
freeList->size = sizeof(heap) - sizeof(Block);
freeList->judge = 0; // 0:free 1:uesd
freeList->next = NULL;
}
void *_malloc(size_t size)
{
// If the size of the request is zero, return NULL
if (size == 0)
{
return NULL;
}
// Align to a multiple of the pointer size
size = (size + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
// If freeList is empty, initialize it.
if (freeList == NULL)
{
initialize();
}
Block *current = freeList;
Block *previous = NULL;
while (current != NULL)
{
if (current->size >= size)
{
// Finding the right sized block of memory
if (current->size > size + sizeof(Block))
{
// Splitting memory blocks
Block *newBlock = (Block *)((char *)current + size + sizeof(Block));
newBlock->size = current->size - size - sizeof(Block);
newBlock->next = current->next;
newBlock->judge = 0;
current->size = size;
current->next = newBlock;
current->judge = 1;
}
// Remove the found memory block from freeList
if (previous == NULL)
{
freeList = current->next;
}
else
{
previous->next = current->next;
}
mergeBlocks();
return (void *)((char *)current + sizeof(Block));
}
// Updating the pointer
previous = current;
current = current->next;
}
// Not enough memory blocks
return NULL;SSS
}
void _free(void *ptr)
{
if (ptr == NULL)
{
// If the pointer is NULL, no operation is performed
printf("Error: No memory to free\n");
return;
}
// Convert the pointer to the block header
struct Block *block = (struct Block *)ptr - 1;
if (block->judge == 0)
{
printf("Error: Wild pointer detected\n");
return;
}
// Add the block back to the free list
if (freeList == NULL || block < freeList)
{
// add the block to the beginning of freeList
block->next = freeList;
block->judge = 0;
freeList = block;
}
else
{
// Find where the block should be inserted
Block *current = freeList;
while (current->next != NULL && current->next < block)
{
current = current->next;
}
block->judge = 0;
block->next = current->next;
current->next = block;
}
// Merge adjacent free memory blocksS
mergeBlocks();
}
S
void mergeBlocks()
{
// Iterate through the chain table and merge adjacent free memory blocks
Block *current = freeList;
Block *prev = NULL;
while (current != NULL && current->next != NULL)
{
if ((char *)current + current->size + sizeof(Block) == (char *)current->next)
{
// Two neighboring blocks of memory are contiguous
current->size += current->next->size + sizeof(Block);
current->next = current->next->next;
}
else
{
// Move to the next block of memory
current = current->next;
}
}
}