问题描述
我是笨蛋,所以请温柔
我一直在尝试为 C++ 编写垃圾收集器库(只是一个项目),但我坚持使用 sbrk() 编写自己的内存分配器,但我不知道内存对齐,我经历了很多文章和视频,但无法绕过它。
我写的东西适用于某种大小,如果我请求 8 倍大小的内存,它就可以工作。
虽然这个答案帮助我修复了我的分配器,但我不知道它是如何工作的
static const size_t align_to = 16;
我不明白为什么用
替换sbrk(size + sizeof(Chunk))
sbrk(size + sizeof(Chunk) + (align_to - 1) & ~(align_to - 1))
有效。
这就是我在简单请求 size + sizeof(Chunk)
***运行时错误:在未对齐的地址 0x55f69e5a724d 内访问类型“struct Chunk”的成员,需要 8 字节对齐 0x55f69e5a724d:注意:指针指向这里 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
#include <unistd.h>
#include <bits/stdc++.h>
using namespace std;
using void_pointer = void*;
struct Chunk {
size_t size; // 8 bytes
bool is_free; // 1 byte
};
using Chunk_pointer = Chunk*;
auto cmp = [](Chunk_pointer a,Chunk_pointer b) -> bool {
return a->size < b->size;
};
class Heap {
set<Chunk_pointer,decltype(cmp)> FreeBlock;
list<Chunk_pointer> ChunkList;
public:
Heap() : FreeBlock { cmp } { }
Chunk_pointer GetFreeBlock(const size_t size) {
auto it {
lower_bound(
FreeBlock.begin(),FreeBlock.end(),size,[](const Chunk_pointer T1,const size_t S) -> bool {
return T1->size < S;
}
)
};
if (it != FreeBlock.end()) {
FreeBlock.erase(it);
return *it; // *it is Chunk_pointer type
}
return nullptr;
}
void_pointer allocate(const size_t size) {
if (size != 0) {
auto available_chunk { GetFreeBlock(size) };
if (available_chunk != nullptr) {
available_chunk->is_free = false;
return reinterpret_cast<void_pointer>(available_chunk + 1);
}
void_pointer old_program_break {
sbrk(size + sizeof(Chunk))
};
if (old_program_break != reinterpret_cast<void_pointer>(-1)) {
Chunk_pointer chunk {
reinterpret_cast<Chunk_pointer>(old_program_break)
};
chunk->is_free = false;
chunk->size = size;
ChunkList.push_back(chunk);
return reinterpret_cast<void_pointer>(chunk + 1);
}
}
return nullptr;
}
};
int main() {
Heap H;
srand(time(NULL));
vector<void_pointer> vec;
for (int i { 0 }; i < 50000; ++i) {
int g = rand() % 1000 + 1;
void_pointer new_chunk { H.allocate(g) };
vec.push_back(new_chunk);
}
return 0;
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)