1

I am implementing a simple MemPool. The MemPool is implemented in the form of LinkList. But i don't know to declare the

static Node * free_mem_head;

correctly.

template <int PIECE_SIZE>
class mempool {
private:
    struct Node {
        Node * next;
        char p_mem[PIECE_SIZE];
    };

    const static size_t bunch_size = 50;
public:
    static Node * free_mem_head;
    mempool();
    ~mempool();

    void * allocate();
    void deallocate(void *);
};




template <int PIECE_SIZE>
mempool<PIECE_SIZE>::mempool() {}

template <int PIECE_SIZE>
mempool<PIECE_SIZE>::~mempool() {

}

template <int PIECE_SIZE>
void* mempool<PIECE_SIZE>::allocate() {
    if (free_mem_head == NULL) {
        size_t size_to_new = bunch_size * sizeof(Node);
        void *new_mem = ::operator new(size_to_new);
        free_mem_head = static_cast<Node*>(new_mem);

        for (int i = 0; i<bunch_size - 1; i++) {
            free_mem_head[i].next = &free_mem_head[i + 1];
        }
        free_mem_head[bunch_size - 1].next = NULL;

        Node *res = free_mem_head;
        free_mem_head = free_mem_head->next;
    }
    else {
        Node * res = free_mem_head;
        free_mem_head = free_mem_head->next;
        return res;
    }
}

template <int PIECE_SIZE>
void  mempool<PIECE_SIZE>::deallocate(void * node_to_free) {
    Node * p = static_cast<Node*> (node_to_free);
    p->next = free_mem_head;
    p = free_mem_head;
}

This is how i use it:

#include <cstring>

class Test {
public:
    Test(int a, int b) :a(a), b(b) {
        strncpy(c, "abc", 3);
        c[3] = 0;
    }
    int a;
    double b;
    char c[100];
private:
    void *operator new(size_t s1);
    void operator delete(void *);
};

and

class Node;
mempool<sizeof(Test)> mempool1;
Node * mempool<sizeof(Test)>::free_mem_head = NULL;
void * Test::operator new(size_t s1) {
    return mempool1.allocate();
}

void Test::operator delete(void *p) {
    mempool1.deallocate(p);
    return;
}

it got compile error: error: specializing member ‘mempool<120>::free_mem_head’ requires ‘template<>’ syntax Node * mempool::free_mem_head=NULL;

YNX
  • 511
  • 6
  • 17
  • Not your problem, but the constructor etc must be defined in the header file (not a cpp file), and if they are not defined in the class, they must be `inline`. – Martin Bonner supports Monica Sep 23 '18 at 07:11
  • Related: [Why can't a constexpr member variable be passed to a function](https://stackoverflow.com/questions/52355223/why-cant-a-static-constexpr-member-variable-be-passed-to-a-function/52355302#52355302) – einpoklum Sep 23 '18 at 08:01

1 Answers1

4

You should define free_mem_head without specialization:

template<int PIECE_SIZE>
typename mempool<PIECE_SIZE>::Node * mempool<PIECE_SIZE>::free_mem_head{};

With C++17 it can be defined inside of the template itself:

static inline Node * free_mem_head{};
user7860670
  • 35,849
  • 4
  • 58
  • 84
  • 1
    Perfect. Additionally, [this](https://stackoverflow.com/questions/3229883/static-member-initialization-in-a-class-template/3229904) question and its answers might be helpful to YNX. – crayzeewulf Sep 23 '18 at 07:10
  • @rafix07 Yeah, you are right. I thought it was a separate class because of `class Node;` declaration. – user7860670 Sep 23 '18 at 07:21