我正在尝试编写一个简单的池分配器,用于在c ++中进行分配和释放,作为uni课程任务的一部分。我们得到了git-user floooh的oryol引擎https://github.com/floooh/oryol/blob/master/code/Modules/Core/Memory/poolAllocator.h的引用,因此我尝试通过将池拆分为在需要时分配的水坑来做类似的事情。从一开始,然后随着内存需求的增加而递增。
在我的案例中,每个水坑都维护着自己的免费节点列表,我在创建第一个水坑时已经失败了:当我尝试访问节点结构数据成员时,我遇到了分段错误。下面是我的池分配器类描述以及用于添加水坑的构造函数和函数。我在allocNewPuddle()中的大写锁定“SEGMENTATION FAULT”中注释了它失败,在该函数中的第10行。
课程描述:
template<class T> class memAllocator {
public:
memAllocator();
~memAllocator();
struct Puddle;
struct mNode {
mNode* nextN;
mNode* prevN;
uint puddle;
};
struct Puddle {
mNode* headN_free;
mNode* headN_occ;
};
uint numPuddles;
static const uint nodesInPuddle = 512;
static const uint maxPuddles = 512;
Puddle* puddles[maxPuddles];
uint nodeSize;
uint elemSize;
uint puddleStructSize;
void allocNewPuddle();
void* allocate();
void deallocate(void* obj);
void* findNextFreeNode();
template<typename... ARGS> T* create(ARGS&&... args);
void destroy(T* obj);
};
构造
template<class T>
memAllocator<T>::memAllocator() // creates instance of allocator starting with one puddle allocated
{
this->numPuddles = 0;
this->nodeSize = sizeof(mNode);
this->elemSize = nodeSize + sizeof(T);
this->puddleStructSize = sizeof(Puddle);
allocNewPuddle();
}
添加一个新的水坑:
template<class T>
void memAllocator<T>::allocNewPuddle() // allocates a new puddle
{
// allocate memory for one puddle
assert(numPuddles < maxPuddles);
Puddle* newPuddle = (Puddle*) malloc(puddleStructSize + nodesInPuddle * elemSize);
// allocate nodes in free list pointed to by puddle struct
newPuddle->headN_free = (mNode*) (newPuddle + puddleStructSize + (nodesInPuddle-1)*elemSize);
for (int i = nodesInPuddle-2; i >= 0; i--) {
mNode* curNode = (mNode*) (newPuddle + puddleStructSize + i*elemSize);
// Fails here when attempting to access mNode struct members
curNode->puddle = numPuddles; // SEGMENTATION FAULT HERE ON FIRST ITERATION
curNode->prevN = nullptr;
curNode->nextN = newPuddle->headN_free;
curNode->nextN->prevN = curNode;
newPuddle->headN_free = curNode;
}
newPuddle->headN_occ = nullptr;
puddles[numPuddles] = newPuddle;
numPuddles++;
}
这是我的main.cc:
#include "memAllocator.h"
#include <iostream>
class Test {
public:
Test();
~Test();
int arr[5];
};
Test::Test() {
for (int i = 0; i < 5; i++) {
this->arr[i] = i;
}
}
Test::~Test() {
std::cout << "destructor called" << std::endl;
}
int main(int argc, char* argv[]) {
memAllocator<Test> memPool = memAllocator<Test> ();
Test* test = memPool.create();
for (int i = 0; i < 5; i++) {
std::cout << test->arr[i] << std::endl;
}
memPool.destroy(test);
for (int i = 0; i < 5; i++) {
std::cout << test->arr[i] << std::endl;
}
}
我的猜测是我正在用c ++指针做一些非常天真的事情,但据我所知,上面应该有用。如果没有,那么我期待好好的责骂。
哦,正如你所看到的那样,我并不打算调整内存,因为它是一个很小的任务,而且据我所知,它不是必不可少的工作它只会使它更快,但这可能会导致是否需要读取和写入错误的内存?
答案 0 :(得分:0)
您的行地址计算错误
mNode* curNode = (mNode*) (newPuddle + puddleStructSize + i*elemSize);
newPuddle 是Puddle指针,但您尝试添加字节。因此,您的新地址远远超出分配的内存缓冲区的末尾。因此,您必须将显式强制转换添加到字节指针(char,uint8_t等)
mNode* curNode = (mNode*) ((char*)newPuddle + puddleStructSize + i*elemSize);
您也必须修复此行
newPuddle->headN_free = (mNode*) (newPuddle + puddleStructSize + (nodesInPuddle-1)*elemSize);