0

我是nooby,所以请温柔

我一直在尝试为 C++ 编写垃圾收集器库(只是一个项目),但我一直坚持使用 sbrk() 编写自己的内存分配器,但我不知道内存对齐,我浏览了很多文章和视频但无法绕过它。

我写的东西适用于某种大小,如果我请求 8 个大小的内存的倍数,它就可以工作。

虽然这个答案帮助我修复了我的分配器,但我不知道它是如何工作的

malloc 实现?

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;
}
4

0 回答 0