c++单线程内存分配器
2015-10-12 14:39
507 查看
*写一个单线程的分配器
本章向你展示如何重载new和delete操作来创建一个基本的内存管理系统。这个系统有很多不足:他将要存储有限的静态数组,他有内存碎片的一些问题并且会漏掉任何已释放的内存.
我将要介绍这些过程当我们分配内存的时候,并且将要强调一些问题。来写这些不同的内存管理的任务。
下面是一个内存分配的结构
struct MemoryAllocationHeader
{
void* pStart = NULL;
void* pNextFree = NULL;
size_t size = 0;
}
这个结构体存储一个指针指向内存并返回一个void* pStart变量,指向下一个释放内存块的pNextFree指针。并且分配这个size变量大小。内存管理并不是用动态内存分配给用户的项目。取代它的是返回一个地址来自内部的静态数组。这个数组将要创造一个未命名的空间。
namespace{
const unsigned int ONE_MEGABYTE = 1024*1024*1024;
char pMemoryHeap[MEGABYTE];
const size_t SIZE_OF_MEMORY_HEADER = sizeof(MemoryAllocationHeader);
}
在这里你能够看到我们分配静态数组1MB的大小。我们知道这个1MB作为char类型在平台是1字节并且我们分配这个数组是1024字节,1024kb大小总共是1,048,576字节。未命名
的命名空间有一个常量来存储我们的MemoryAllocationHeader对象的大小,以及计算sizeof它的函数。这个大小是12字节:4字节的pStart指针,4字节的pNextFree指针以及4字节的大小变量。
接下来我们要重载这个new操作符。new和delete函数你将要看到:
void* operator new(size_t size)
{
MemoryAllocationHeader* pHeader =
reinterpret_cast<MemoryAllocationHeader*>(pMemoryHeap);
while(pHeader != NULL && pHeader->pNextFree != NULL)
{
pHeader = reinterpret_cast<MemoryAllocationHeader*>(pHeader->pNextFree);
}
pHeader->pStart = reinterpret_cast<char*>(pHeader)+SIZE_OF_MEMORY_HEADER;
pHeader->pNextFree = reinterpret_cast<char*>(pHeader->pStart) + size;
pHeader->size = size;
return pHeader->pStart;
}
这个new操作符进行大小的分配我们将要返回这个void*并且开始写一个内存块.这个功能将要开始循环在存在的内存分配直到它发现这个分配的模块为NULL在pNextFree变量中.
我们要分配内存,我们也要释放这个内存。重载delete操作符来清除这个分配来自于我们的堆中。
void operator delete(void* pMemory)
{
MemoryAllocationHeader* pLast = NULL;
MemoryAllocationHeader* pCurrent =
reinterpret_cast<MemoryAllocationHeader*>(pMemoryHeap);
while(pCurrent != NULL && pCurrent->pStart != NULL)
{
pLast = pCurrent;
pCurrent = reinterpret_cast<MemoryAllocationHeader*>(pCurrent->pNextFree);
}
if(pLast != NULL)
{
pLast->pNextFree = reinterpret_cast<char*>(pCurrent->pNextFree);
}
pCurrent->pStart = NULL;
pCurrent->pNextFree = NULL;
pCurrent->size = 0;
}
*打印功能
void PrintAllocations()
{
MemoryAllocationHeader* pHeader =
reinterpret_cast<MemoryAllocationHeader*>(pMemoryHeap);
while(pHeader != NULL)
{
qDebug()<<pHeader<<endl;
qDebug()<<pHeader->pStart<<endl;
qDebug()<<pHeader->pNextFree<<endl;
qDebug()<<pHeader->size<<endl;
pHeader = reinterpret_cast<MemoryAllocationHeader*>(pHeader->pNextFree);
}
}
*可设计类实现
class Simple
{
public:
void* operator new(size_t size);
void operator delete(void* pMemory);
};
void* Simple::operator new(size_t size)//实现同上
void Simple::operator delete(void* pMemory)//实现同上
int main(int argc, char *argv[])
{
Simple* pSimple = new Simple();
PrintAllocations();
delete pSimple;
//test the demo!!!
}
本章向你展示如何重载new和delete操作来创建一个基本的内存管理系统。这个系统有很多不足:他将要存储有限的静态数组,他有内存碎片的一些问题并且会漏掉任何已释放的内存.
我将要介绍这些过程当我们分配内存的时候,并且将要强调一些问题。来写这些不同的内存管理的任务。
下面是一个内存分配的结构
struct MemoryAllocationHeader
{
void* pStart = NULL;
void* pNextFree = NULL;
size_t size = 0;
}
这个结构体存储一个指针指向内存并返回一个void* pStart变量,指向下一个释放内存块的pNextFree指针。并且分配这个size变量大小。内存管理并不是用动态内存分配给用户的项目。取代它的是返回一个地址来自内部的静态数组。这个数组将要创造一个未命名的空间。
namespace{
const unsigned int ONE_MEGABYTE = 1024*1024*1024;
char pMemoryHeap[MEGABYTE];
const size_t SIZE_OF_MEMORY_HEADER = sizeof(MemoryAllocationHeader);
}
在这里你能够看到我们分配静态数组1MB的大小。我们知道这个1MB作为char类型在平台是1字节并且我们分配这个数组是1024字节,1024kb大小总共是1,048,576字节。未命名
的命名空间有一个常量来存储我们的MemoryAllocationHeader对象的大小,以及计算sizeof它的函数。这个大小是12字节:4字节的pStart指针,4字节的pNextFree指针以及4字节的大小变量。
接下来我们要重载这个new操作符。new和delete函数你将要看到:
void* operator new(size_t size)
{
MemoryAllocationHeader* pHeader =
reinterpret_cast<MemoryAllocationHeader*>(pMemoryHeap);
while(pHeader != NULL && pHeader->pNextFree != NULL)
{
pHeader = reinterpret_cast<MemoryAllocationHeader*>(pHeader->pNextFree);
}
pHeader->pStart = reinterpret_cast<char*>(pHeader)+SIZE_OF_MEMORY_HEADER;
pHeader->pNextFree = reinterpret_cast<char*>(pHeader->pStart) + size;
pHeader->size = size;
return pHeader->pStart;
}
这个new操作符进行大小的分配我们将要返回这个void*并且开始写一个内存块.这个功能将要开始循环在存在的内存分配直到它发现这个分配的模块为NULL在pNextFree变量中.
我们要分配内存,我们也要释放这个内存。重载delete操作符来清除这个分配来自于我们的堆中。
void operator delete(void* pMemory)
{
MemoryAllocationHeader* pLast = NULL;
MemoryAllocationHeader* pCurrent =
reinterpret_cast<MemoryAllocationHeader*>(pMemoryHeap);
while(pCurrent != NULL && pCurrent->pStart != NULL)
{
pLast = pCurrent;
pCurrent = reinterpret_cast<MemoryAllocationHeader*>(pCurrent->pNextFree);
}
if(pLast != NULL)
{
pLast->pNextFree = reinterpret_cast<char*>(pCurrent->pNextFree);
}
pCurrent->pStart = NULL;
pCurrent->pNextFree = NULL;
pCurrent->size = 0;
}
*打印功能
void PrintAllocations()
{
MemoryAllocationHeader* pHeader =
reinterpret_cast<MemoryAllocationHeader*>(pMemoryHeap);
while(pHeader != NULL)
{
qDebug()<<pHeader<<endl;
qDebug()<<pHeader->pStart<<endl;
qDebug()<<pHeader->pNextFree<<endl;
qDebug()<<pHeader->size<<endl;
pHeader = reinterpret_cast<MemoryAllocationHeader*>(pHeader->pNextFree);
}
}
*可设计类实现
class Simple
{
public:
void* operator new(size_t size);
void operator delete(void* pMemory);
};
void* Simple::operator new(size_t size)//实现同上
void Simple::operator delete(void* pMemory)//实现同上
int main(int argc, char *argv[])
{
Simple* pSimple = new Simple();
PrintAllocations();
delete pSimple;
//test the demo!!!
}
相关文章推荐
- c语言正则表达式应用
- hdu 2795 Billboard(线段树+单点更新)
- hdu 1754 I Hate It(线段树)
- hdu 1166敌兵布阵(线段树)
- hdu 1556 Color the ball (线段树之扫描线)
- C/C++ IDE之C-Free(配置GCC、Visual C++、Borland C++编译器)
- hdu 2024 C语言合法标识符
- c++中vector的用法
- C语言编译和链接和加载
- 爬爬爬之路:C语言(三) 入门篇3
- C++字符串中查找子字符串并替换
- 关于 switch 语句的执行过程
- Tee Chart Usage in MFC
- C/C++程序编译步骤 如何生成可执行文件
- 把《C++Primer》读薄
- c++在vs2010中操作Mysql的讲解
- 配置文件读写(c语言指针实现)
- 生成1到n的随机排列(C++实现)
- 计数排序
- C++ unordered_map remove 实现哈希表移除