c++ - 为什么实例化后什么也没有发生? (C++ 内存分配器实现)

标签 c++ memory memory-management allocator

对于我最近获得的 C++ 类(class)来说,这是一个相当奇怪的作业。这个想法是使用双向链表在 C++ 中实现一个简单的内存分配器。我的 C++ 仅限于解决 Codeforces 上的问题,所以我不知道为什么似乎什么都没有打印出来。这是代码:

main.cpp

#include <iostream>
#include "tests.h"

int main() {
    Tests tests = Tests();
    tests.run();

    return 0;
}

分配器.cpp

#include <iostream>
#include "allocator.h"

void* CleverPtr::get() const {
    return data;
}

Allocator::Allocator() {

    Allocator(100);//100 Bite
}

Allocator::Allocator(size_t size) {

    memory = (char*)malloc(size);

    head->next = nullptr;
    head->prev = nullptr;
    head->size = size;
    head->block = memory;
    head->state = FREE;
}

CleverPtr Allocator::alloc(size_t size) {

    dl_l *ptr = head;
    bool find = false;

    while (ptr){
        if (ptr->state == FREE and ptr->size >= size) {
            find = true;
            break;
        }
        ptr = ptr->next;
    }

    if (find) {
        dl_l new_block;
        new_block.next = nullptr;
        new_block.prev = nullptr;
        new_block.block = ptr->block;
        new_block.size = size;
        new_block.state = OCCUPIED;

        ptr->block = (char*)((uintptr_t)(ptr->block) + size);

        add_to_list(ptr->prev, &new_block, ptr);

        return CleverPtr(new_block.block);
    }

    return CleverPtr(nullptr);
}
void Allocator::free(CleverPtr &ptr) {
    dl_l * node = (dl_l*)((char *)ptr.get() - offsetof(dl_l, block));

    node->state = FREE;
}

void Allocator::defrag() {
    dl_l *ptr = head;

    while(ptr) {
        if (ptr->next) {
            if (ptr->state == FREE and ptr->next->state == FREE) {
                ptr->size += ptr->next->size;
                remove_from_list(ptr->next);
            }
        }
        ptr = ptr->next;
    }
}

std::list<dl_l*> Allocator::show_busy_blocks() const {
    dl_l *ptr = head;

    std::list<dl_l*> busy_blocks = std::list<dl_l*>();

    while(ptr) {
        if (ptr->state == OCCUPIED) {
            busy_blocks.push_back(ptr);
        }
        ptr = ptr->next;
    }

    return busy_blocks;
}

std::list<dl_l*> Allocator::show_free_blocks() const {
    dl_l *ptr = head;

    std::list<dl_l*> free_blocks = std::list<dl_l*>();

    while(ptr) {
        if (ptr->state == FREE) {
            free_blocks.push_back(ptr);
        }
        ptr = ptr->next;
    }

    return free_blocks;
}

测试.cpp

#include <cassert>
#include "tests.h"


void Tests::run() {

    Allocator allocator = Allocator(100);

    //CleverPtr ptr = allocator.alloc(10);

    //std::list<dl_l*> busy_blocks = allocator.show_busy_blocks();

    //assert(busy_blocks.size()==1);
    cout << "Test 1" << endl;

    //CleverPtr ptr1 = allocator.alloc(10);
   // std::list<dl_l*> busy_blocks1 = allocator.show_busy_blocks();
    //assert(busy_blocks1.size()==2);
    cout << "Test 2" << endl;

   // CleverPtr ptr2 = allocator.alloc(10);
   // std::list<dl_l*> busy_blocks2 = allocator.show_busy_blocks();
    //assert(busy_blocks2.size()==3);
    cout << "Test 3" << endl;

   // allocator.free(ptr1);
    //std::list<dl_l*> free_blocks = allocator.show_free_blocks();
    //assert(free_blocks.size()==2);
    cout << "Test 4" << endl;

    //allocator.free(ptr2);
    //std::list<dl_l*> free_blocks1 = allocator.show_free_blocks();
   // assert(free_blocks1.size()==3);
    cout << "Test 5" << endl;

    //allocator.defrag();
    //std::list<dl_l*> free_blocks2 = allocator.show_free_blocks();
    //assert(free_blocks1.size()==1);
    cout << "Test 6" << endl;

    cout << "Tests done successfully" << endl;
}

分配器.h

#include <algorithm>
#include <iostream>
#include <list>
#include <cstdio>
#include "dl_list.h"

#ifndef ALLOCATORLT_ALLOCATOR_H
#define ALLOCATORLT_ALLOCATOR_H

typedef struct{
    int* offset;
    int size;
} block;

using namespace std;

class CleverPtr {
    void* data;

public:
    void* get() const;
    explicit CleverPtr(void* data): data(data){}
};

class Allocator {
    private:
        char* memory;
        dl_l* head;



    public:
        Allocator();
        explicit Allocator(size_t size);

        std::list<dl_l*> show_busy_blocks() const;
        std::list<dl_l*> show_free_blocks() const;

        CleverPtr alloc(size_t size);
        void free(CleverPtr&);
        void defrag();
};


#endif //ALLOCATORLT_ALLOCATOR_H

dl_list.h

#include <cstdint>

#ifndef ALLOCATORLT_LIST_H
#define ALLOCATORLT_LIST_H

#endif //ALLOCATORLT_LIST_H
enum STATES {FREE, OCCUPIED};

typedef struct dl_list {
    struct dl_list *next;
    struct dl_list *prev;
    int size;
    char * block;
    int state;
} dl_l;

static void add_to_list(dl_l *prev_node, dl_l *new_node, dl_l *next_node) {
    if (prev_node) {
        prev_node->next = new_node;
        new_node->prev = prev_node;
    }

    if (next_node) {
        next_node->prev = new_node;
        new_node->next = next_node;
    }
}

static void remove_from_list(dl_l *node) {
    if (node->prev)
        node->prev->next = node->next;

    if (node->next)
        node->next->prev = node->prev;
}

测试.h

#include "allocator.h"

#ifndef ALLOCATORLT_TESTS_H
#define ALLOCATORLT_TESTS_H


class Tests {

public:
    void run();
};


#endif //ALLOCATORLT_TESTS_H

我必须插入所有代码才能重现问题。如您所见,我注释掉了 tests.cpp 中的所有代码行,因为它们对输出没有任何影响。

Allocator allocator = Allocator(100); 行之后的所有 cout 都将被忽略,这意味着该构造函数调用有问题。不过,我不知道到底是什么。

有人可以帮我解决这个问题吗?

附言如果您碰巧注意到任何其他错误或严重错误(我怀疑有一些),请告诉我。谢谢

最佳答案

您永远不会为 head 赋值,但您可以在构造函数中使用 head->next = nullptr; 取消引用它。 head 很可能是 NULL 或指向垃圾,当您尝试访问 next 指针时会导致错误。

看这段代码:

Allocator::Allocator(size_t size) {

    memory = (char*)malloc(size);

    head->next = nullptr;
    head->prev = nullptr;
    head->size = size;
    head->block = memory;
    head->state = FREE;
}

您还没有将 head 设置为指向任何东西。你认为 head->next 在这里是什么?

我怀疑你的意思是:

Allocator::Allocator(size_t size) {
    head = NULL;
}

没有理由在这里分配 block ,因为没有任何东西需要指向 block 的指针。

关于c++ - 为什么实例化后什么也没有发生? (C++ 内存分配器实现),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59072665/

相关文章:

c++ - 将 "pointer to pointer"传递给模板函数

c++ - 如何就地修改一维数组的每个元素?

python - 使用 Python 在内存中的文件对象

java - Playframework 的内存使用情况

ios - UIImageView 在不在 View 中时是否释放资源?

c++ - 中断 C 函数执行并返回到 C++ 调用者

c++ - 集合中的智能指针多态性

c++ - 在 Rcpp 中构建数据框

javascript - 如何强制 Firefox(版本 6)释放内存?

java - 在构造函数中泄漏它