做这个内存池主要是为了完成一道面试题,题目在代码中。

代码

 #include <iostream>
#include<string>
#include <list>
using namespace std; //一个简单的内存池,池中保存3块内存分别为1k,2k,4k
//实现池子的malloc(size)和free(void*)操作
//不考虑跨块申请内存情况 class node
{
public:
int offset;//相对于起始地址偏移
bool flag;//是有效地址还是已经分配地址
int len;
node()
{
offset=;
flag=true;
len=;
}
node(int sz)
{
offset=;
flag=true;
len=sz;
}
}; class memPool
{
public:
memPool()
{
m_First_Count= ;
m_Second_Count = *;
m_Third_Count = *;
m_First_Address = new char[m_First_Count];
m_Second_Address = new char[m_Second_Count];
m_Third_Address = new char[m_Third_Count]; first.insert(first.begin(),new node());
second.insert(second.begin(),new node(*));
third.insert(third.begin(),new node(*));
}
~memPool()
{
delete[]m_First_Address;
delete[]m_Second_Address;
delete[]m_Third_Address;
m_First_Address = NULL;
m_Second_Address = NULL;
m_Third_Address = NULL; }
char* myMalloc(const int memSize)
{
//采用首次适应算法
list<node*>::iterator it;
if (memSize <= m_First_Count)
{
it = first.begin();
while(it!=first.end())
{
if (((*it)->len)>= memSize &&(*it)->flag == true)
{
(*it)->flag = false;
int temp = (*it)->len;
(*it)->len = memSize;
if (temp - memSize >)
{
node *obj = new node;
obj->flag=true;
obj->len = temp - memSize;
obj->offset = (*it)->offset + memSize;
it++;
first.insert(it,obj);
it--;
it--;
m_First_Count-=memSize;
cout << "malloc "<< memSize << " in first memery"<<endl;
return m_First_Address+(*it)->offset;
}
}
it++;
} } if (memSize <= m_Second_Count)
{
it = second.begin();
while(it!=second.end())
{
if (((*it)->len)>= memSize&&(*it)->flag == true)
{
(*it)->flag = false;
int temp = (*it)->len;
(*it)->len = memSize;
if (temp - memSize >)
{
node *obj = new node;
obj->flag=true;
obj->len = temp - memSize;
obj->offset = (*it)->offset + memSize;
it++;
second.insert(it,obj);
it--;
it--;
m_Second_Count-=memSize;
cout << "malloc "<< memSize << "in second memery"<<endl;
return m_Second_Address+(*it)->offset;
}
}
it++;
} } if (memSize <= m_Third_Count)
{
it = third.begin();
while(it!=third.end())
{
if (((*it)->len)>= memSize&&(*it)->flag == true)
{
(*it)->flag = false;
int temp = (*it)->len;
(*it)->len = memSize;
if (temp - memSize >)
{
node *obj=new node;
obj->flag=true;
obj->len = temp - memSize;
obj->offset = (*it)->offset + memSize;
it++;
third.insert(it,obj);
it--;
it--;
m_Third_Count-=memSize;
cout << "malloc "<< memSize << "in third memery"<<endl;
return m_Third_Address+(*it)->offset;
}
}
it++;
} } cout<<"no memery\n";
return NULL; }
/************************************************************************/
/* 算法思路是第一步定位这个指针位于哪一个内存块,第二步在对应内存块中找到*/
/*其node,然后判断node前后是否都为有效内存,也就是没有被利用的内存块*/
/************************************************************************/
void memFree(void* address_arg)
{
char *freeAddress= static_cast<char*>(address_arg);
int offset;
list<node*>::iterator it;
if (freeAddress >= m_First_Address && freeAddress < (m_First_Address+))//位于第一块
{
offset = freeAddress - m_First_Address;
it = first.begin(); while(it!= first.end())//定位offset
{
if (offset == (*it)->offset)
break; it++;
}
if (it == first.end())//没有找到offset
{
cout << "In first memery,there is no memery of freeaddress"<<endl;
return;
} if((*it)->flag == true)//找到offset,但是这块内存没有分配
{
cout << "In first memery,the freeAddress is valid,you can't free it"<<endl;
return;
}
(*it)->flag = true; int len = (*it)->len;
int count=;
if (it!=first.end())//判断it后继节点是否被分配
{
it++;
if ((*it)->flag == true)
{
len+=(*it)->len;
count++;
}
it--;
}
if (it!=first.begin())
{
it--;
if ((*it)->flag == true)
{
len+=(*it)->len;
count++;
}
else
it++;
}
(*it)->len = len;
it++;
while(count--)
{
it = first.erase(it);//erase返回删除节点的后继节点 } cout << "free success"<<endl;
return; }
else if (freeAddress >= m_Second_Address && freeAddress < (m_Second_Address+*))//位于第二块
{
offset = freeAddress - m_Second_Address;
it = second.begin(); while(it!= second.end())//定位offset
{
if (offset == (*it)->offset)
break; it++;
}
if (it == second.end())//没有找到offset
{
cout << "In second memery,there is no memery of freeaddress"<<endl;
return;
} if((*it)->flag == true)//找到offset,但是这块内存没有分配
{
cout << "In second memery,the freeAddress is valid,you can't free it"<<endl;
return;
}
(*it)->flag = true; int len = (*it)->len;
int count=;
if (it!=second.end())//判断it后继节点是否被分配
{
it++;
if ((*it)->flag == true)
{
len+=(*it)->len;
count++;
}
it--;
}
if (it!=second.begin())
{
it--;
if ((*it)->flag == true)
{
len+=(*it)->len;
count++;
}
else
it++;
}
(*it)->len = len;
it++;
while(count--)
{
it = second.erase(it);
} cout << "free success"<<endl;
return;
}
else if (freeAddress >= m_Third_Address && freeAddress < (m_Third_Address+*))//位于第三块
{
offset = freeAddress - m_Third_Address;
it = third.begin(); while(it!= third.end())//定位offset
{
if (offset == (*it)->offset)
break; it++;
}
if (it == third.end())//没有找到offset
{
cout << "In third memery,there is no memery of freeaddress"<<endl;
return;
} if((*it)->flag == true)//找到offset,但是这块内存没有分配
{
cout << "In third memery,the freeAddress is valid,you can't free it"<<endl;
return;
}
(*it)->flag = true; int len = (*it)->len;
int count=;
if (it!=third.end())//判断it后继节点是否被分配
{
it++;
if ((*it)->flag == true)
{
len+=(*it)->len;
count++;
}
it--;
}
if (it!=third.begin())
{
it--;
if ((*it)->flag == true)
{
len+=(*it)->len;
count++;
}
else
it++;
}
(*it)->len = len;
it++;
while(count--)
{
it = third.erase(it);
} cout << "free success"<<endl;
return;
}
else
{
cout << "the memery to be freed is invalid\n";
}
return;
}
private:
char *m_First_Address;//每一块内存起始地址
char *m_Second_Address;
char *m_Third_Address;
int m_First_Count;//剩余有效地址大小,不一定是连续,是第一块内存中所有有效之和
int m_Second_Count;
int m_Third_Count;
list<node*> first;
list<node*> second;
list<node*> third; };
int main()
{
memPool obj;
char *ptr1 = obj.myMalloc();
char *ptr2 = obj.myMalloc();
char *ptr3 = obj.myMalloc();
char *ptr4 = obj.myMalloc(*+);
obj.memFree(ptr2);
obj.memFree(ptr3); return ;
}

一个简易内存池(C++)的更多相关文章

  1. 基于Win32 SDK实现的一个简易线程池

    利用C++实现了一个简易的线程池模型(基于Win32 SDK),方便使用多线程处理任务.共包含Thread.h.Thread.cpp.ThreadPool.h.ThreadPool.cpp四个源文件. ...

  2. C++内存管理:简易内存池的实现

    什么是内存池? 在上一篇 C++内存管理:new / delete 和 cookie中谈到,频繁的调用 malloc 会影响运行效率以及产生额外的 cookie, 而内存池的思想是预先申请一大块内存, ...

  3. [Golang] 一个简易代理池

    晚上写了一个代理池,就是在一个代理网站上爬取代理ip和端口以及测试是否可用.接下来可能考虑扩展成一个比较大的 golang实现的代理池. 简易版代码: package main import ( &q ...

  4. 对象池与.net—从一个内存池实现说起

    本来想写篇关于System.Collections.Immutable中提供的ImmutableList里一些实现细节来着,结果一时想不起来源码在哪里--为什么会变成这样呢--第一次有了想写分析的源码 ...

  5. nginx源码分析—内存池结构ngx_pool_t及内存管理

    Content 0. 序 1. 内存池结构 1.1 ngx_pool_t结构 1.2 其他相关结构 1.3 ngx_pool_t的逻辑结构 2. 内存池操作 2.1 创建内存池 2.2 销毁内存池 2 ...

  6. nginx源代码分析之内存池实现原理

    建议看本文档时结合nginx源代码. 1.1   什么是内存池?为什么要引入内存池? 内存池实质上是接替OS进行内存管理.应用程序申请内存时不再与OS打交道.而是从内存池中申请内存或者释放内存到内存池 ...

  7. 内存池-转载自IBM

    [转载自IBM]讲的很好~推荐看看 6.1 自定义内存池性能优化的原理 如前所述,读者已经了解到"堆"和"栈"的区别.而在编程实践中,不可避免地要大量用到堆上的 ...

  8. Boost内存池使用与测试

    目录 Boost内存池使用与测试 什么是内存池 内存池的应用场景 安装 内存池的特征 无内存泄露 申请的内存数组没有被填充 任何数组内存块的位置都和使用operator new[]分配的内存块位置一致 ...

  9. 内存分配(new/delete,malloc/free,allocator,内存池)

    以下来源http://www.cnblogs.com/JCSU/articles/1051826.html 程序员们经常编写内存管理程序,往往提心吊胆.如果不想触雷,唯一的解决办法就是发现所有潜伏的地 ...

随机推荐

  1. CSS公用

    *{font-size: 100px;} body,span,h1,h2,h3,h4,h5,h6,li,ul,p,em,strong,ol,form,pre,input,article,header, ...

  2. 云 MongoDB 优化让 LBS 服务性能提升十倍

    欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 随着国内服务共享化的热潮普及,共享单车,共享雨伞,共享充电宝等各种服务如雨后春笋,随之而来的LBS服务定位问题成为了后端服务的一个挑战.M ...

  3. Count(*), Count(1) 和Count(字段)的区别

    1.  count(1) and count(*) 当表的数据量大些时,对表作分析之后,使用count(1)还要比使用count(*)用时多了!  从执行计划来看,count(1)和count(*)的 ...

  4. Centos7环境下使用Nginx托管.Net Core应用程序

    一.安装.Net Core 参考官方文档:https://www.microsoft.com/net/core#linuxcentos 1.添加dotnet产品Feed 在安装.NET Core之前, ...

  5. apollo实现c#与android消息推送(三)

    3 实现c#消息推送服务 c#实现消息推送必须引入M2Mqtt.dll,源码 a 连接apache apollo代理服务器的代码.需要引入using uPLibrary.Networking.M2Mq ...

  6. Merge Two Binary Trees

    Given two binary trees and imagine that when you put one of them to cover the other, some nodes of t ...

  7. 使用SQLite做本地数据缓存的思考

    前言 在一个分布式缓存遍地都是的环境下,还讲本地缓存,感觉有点out了啊!可能大家看到标题,就没有想继续看下去的欲望了吧.但是,本地缓存的重要性也是有的! 本地缓存相比分布式缓存确实是比较out和比较 ...

  8. javascript中DOM集锦(二)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  9. 【技巧】datagrid锁定列后重新加载时出现错位问题的解决

    [问题描述]:有时候datagrid设置了锁定列后,在重新加载datagrid数据时,出现锁定列与非锁定列数据错位的问题,如图: [问题分析]:查看css样式我们发现,锁定的列和非锁定的列属于两个不同 ...

  10. 将JavaScript转化为C#

    因为一个需求,不得不将JavaScript转化为C#. 其实有强大的 Node.js. 说说代码, 其实可以使用dynamic 来实现.但是dynamic有很多问题. 直接上代码吧,不是很难,就是很啰 ...