@@ -31,6 +31,45 @@ namespace infini
3131
3232 // =================================== 作业 ===================================
3333 // TODO: 设计一个算法来分配内存,返回起始地址偏移量
34+ // Use First Fit algorithm: find the first free block that is large enough
35+ for (auto it = freeBlocksByAddr.begin (); it != freeBlocksByAddr.end (); ++it)
36+ {
37+ size_t addr = it->first ;
38+ size_t blockSize = it->second ;
39+
40+ if (blockSize >= size)
41+ {
42+ // Found a suitable block
43+ // Remove this block from both maps
44+ freeBlocksByAddr.erase (it);
45+ freeBlocksByEnd.erase (addr + blockSize);
46+
47+ // If the block is larger than needed, add the remaining part back
48+ if (blockSize > size)
49+ {
50+ size_t newAddr = addr + size;
51+ size_t newSize = blockSize - size;
52+ freeBlocksByAddr[newAddr] = newSize;
53+ freeBlocksByEnd[newAddr + newSize] = newSize;
54+ }
55+
56+ // Update memory usage statistics
57+ used += size;
58+ if (used > peak)
59+ {
60+ peak = used;
61+ }
62+
63+ return addr;
64+ }
65+ }
66+
67+ // No suitable free block found, allocate at the end
68+ size_t addr = peak;
69+ used += size;
70+ peak += size;
71+
72+ return addr;
3473 // =================================== 作业 ===================================
3574
3675 return 0 ;
@@ -43,6 +82,75 @@ namespace infini
4382
4483 // =================================== 作业 ===================================
4584 // TODO: 设计一个算法来回收内存
85+ // Update memory usage
86+ used -= size;
87+
88+ size_t blockStart = addr;
89+ size_t blockEnd = addr + size;
90+ size_t blockSize = size;
91+
92+ // Special case: if freeing the block at the end, just reduce peak
93+ if (blockEnd == peak)
94+ {
95+ // Check if we can merge with a previous free block at the end
96+ auto prevIt = freeBlocksByEnd.find (blockStart);
97+ if (prevIt != freeBlocksByEnd.end ())
98+ {
99+ // Merge with the previous block and reduce peak further
100+ size_t prevSize = prevIt->second ;
101+ size_t prevStart = blockStart - prevSize;
102+
103+ // Remove the previous block from both maps
104+ freeBlocksByAddr.erase (prevStart);
105+ freeBlocksByEnd.erase (blockStart);
106+
107+ // Reduce peak to the start of the merged block
108+ peak = prevStart;
109+ }
110+ else
111+ {
112+ // Just reduce peak
113+ peak = blockStart;
114+ }
115+ return ;
116+ }
117+
118+ // Try to merge with the previous adjacent free block
119+ auto prevIt = freeBlocksByEnd.find (blockStart);
120+ if (prevIt != freeBlocksByEnd.end ())
121+ {
122+ // Found a previous adjacent block
123+ size_t prevSize = prevIt->second ;
124+ size_t prevStart = blockStart - prevSize;
125+
126+ // Remove the previous block from both maps
127+ freeBlocksByAddr.erase (prevStart);
128+ freeBlocksByEnd.erase (blockStart);
129+
130+ // Merge: extend the current block backwards
131+ blockStart = prevStart;
132+ blockSize += prevSize;
133+ }
134+
135+ // Try to merge with the next adjacent free block
136+ auto nextIt = freeBlocksByAddr.find (blockEnd);
137+ if (nextIt != freeBlocksByAddr.end ())
138+ {
139+ // Found a next adjacent block
140+ size_t nextSize = nextIt->second ;
141+
142+ // Remove the next block from both maps
143+ freeBlocksByAddr.erase (blockEnd);
144+ freeBlocksByEnd.erase (blockEnd + nextSize);
145+
146+ // Merge: extend the current block forwards
147+ blockSize += nextSize;
148+ blockEnd += nextSize;
149+ }
150+
151+ // Add the merged (or original) free block to both maps
152+ freeBlocksByAddr[blockStart] = blockSize;
153+ freeBlocksByEnd[blockEnd] = blockSize;
46154 // =================================== 作业 ===================================
47155 }
48156
0 commit comments