当前位置: 首页 > news >正文

网站建设公司厂人大常委会委员长

网站建设公司厂,人大常委会委员长,做国际交友网站翻译,wordpress修改主题头部图片头文件<stl_alloc.h>专门用于管理内存&#xff0c;内存的申请和释放&#xff08;我们可以想象成operator new&#xff09; 头文件<stl_construct.h>&#xff0c;专门管理某个内存空间中的构建或者析构对象。 头文件<stl_uninitialized.h>是对大块内存的填充和…

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
头文件<stl_alloc.h>专门用于管理内存,内存的申请和释放(我们可以想象成operator new)
头文件<stl_construct.h>,专门管理某个内存空间中的构建或者析构对象。
头文件<stl_uninitialized.h>是对大块内存的填充和拷贝

在这里插入图片描述
在多线程情况下,需要加锁和解锁。
在这里插入图片描述
当这个内存块的大小大于128字节,我们认为这个块足够大,把它交给第一级配置器(直接使用malloc和free)去配置。
当这个内存块的大小小于128字节,我们认为这个块小,为了降低额外负担(我们malloc分配一块内存时,真实的情况是,系统分配的内存大小远大于我们申请的大小,包含了4字节的上越界标记,4字节的下越界标记和28字节的头部信息,造成内存和时间效率降低),,我们把它交给内存池,第二级配置器。
在这里插入图片描述

封装第一级配置器

包装了C语言的malloc ,free , realloc

#ifndef YHP_ALLOC_H
#define YHP_ALLOC_H
#include<iostream>
namespace yhp
{
#if 0
#include<new>
#define __THROW_BAD_ALLOC throw std::bad_alloc;
#elif !defined(__THREAD_BAD_ALLOC)//如果没有定义 ,就打印内存溢出 
//#include<iostream>
#define __THROW_BAD_ALLOC std::cerr<<"out of memory"<<std::endl; exit(1)
#endif//第一级配置器 
template<int inst>
class __malloc_alloc_template
{
private:static void *oom_malloc(size_t n)//分配n个空间 //要么能申请到空间然后走人,要么抛出异常 {void * result = NULL;void (*my_malloc_handler)() = NULL;for(;;)//无限循环 {my_malloc_handler = __malloc_alloc_oom_handler;if(NULL == my_malloc_handler){__THROW_BAD_ALLOC;//调用宏,抛出异常 }(*my_malloc_handler)();
//回调函数,1、释放更多的空间2、指明新的释放函数3、如果没有指明新的释放函数把程序结束掉 result = malloc(n);if(result != NULL){return result;//成功了,内存的返回 }}}static void *oom_realloc(void *p,size_t new_sz)//追加内存的分配 {void * result = NULL;void (*my_malloc_handler)() = NULL;for(;;){my_malloc_handler = __malloc_alloc_oom_handler;if(NULL == my_malloc_handler){__THROW_BAD_ALLOC;}(*my_malloc_handler)();result = realloc(p,new_sz);if(result != NULL){return result;}}}static void (*__malloc_alloc_oom_handler)();//函数指针 
public:static void *allocate(size_t n)//n是字节个数,不是元素的个数,内存的分配 {void *result = malloc(n);if(NULL == result){result = oom_malloc(n);}return result;}static void deallocate(void *p,size_t n)//释放内存空间 {free(p);}static void *reallocate(void *p,size_t old_sz,size_t new_sz)//追加内存空间 {void *result = realloc(p,new_sz);if(NULL == result){result = oom_realloc(p,new_sz);}return result;}static void (*set_malloc_handler(void (*f)()) )() {void (*old)() = __malloc_alloc_oom_handler;__malloc_alloc_oom_handler = f;return old;}
};template<int inst>
void (*__malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = NULL;
///
typedef __malloc_alloc_template<0>   malloc_alloc;

测试代码如下
在这里插入图片描述

如果我们在程序的运行过程中,内存不足了怎么办?

进入主函数之前,p1,p2指向相应的申请的内存空间。
在这里插入图片描述
我们写了一个函数yhp,把p1释放掉,把第二个函数rj放进去,
rj这个函数的作用是释放p2,如果释放空间后,把空放进去。

在这里插入图片描述
然后我们书写主函数

在这里插入图片描述
运行程序,我们看到,首先调用set_malloc_handler,把这个函数指针指向hp这个函数,申请空间的时候,调动malloc,如果我把result置为空,要调动oom_malloc,my_malloc_handler获得了hp的指针,不为空,调动hp的函数释放更多的空间,把rj这个函数注册进去,假设我再把result置为空,没有申请到空间,my_malloc_handler获得了rj的指针,不为空,再调动rj的释放内存函数,malloc再申请,我们又给个result=0,my_malloc_handler变成了空,调动宏,打印了错误,程序退出,内存用完了。
也就是说,先开始估算这个程序所需要的内存,直接先占领,我的程序在运行的过程中,如果内存不足,通过oom_malloc,调动回调函数,首先指向hp函数,释放内存,再申请空间,释放内存,如果还要申请,为空了,就确实是内存用完了。
注意:rj的函数里直接置为空放进去。防止如果再调用回调函数,那个回调函数中又占用了空间,但是内存不足,从而造成了死循环。

第二级配置器

在这里插入图片描述
在这里插入图片描述
如下图,最上面的一排数字代表内存的大小。下排的数字代表数组的下标
在这里插入图片描述
在最开始的时候,都是空。假设我们需要12个字节,选取 1下标对应的16个字节的内存块,没有找到,我们就先malloc 16*20 *2=640个字节的内存空间,进行注水,提取出320字节,把16个字节给给用户,剩下19个16字节块变成一个块一个块,一个块大小为16个字节,以链表的形式,链起来,头结点指向1下标的位置,如果我们还需要16个字节,就使用链表的头删,
在这里插入图片描述
这样比malloc速度快多了,而且这16个字节是没有上越界下越界标记和头部信息的。
如果我们需要40个字节,下标4的位置为空,STL就要把剩下的320字节分了,40乘以20大于320,320除以40是8,刚好分配8个块出去。把第一个块给用户,剩下的字节划分为7个块,划分成一块一块大小为40字节,以链表的形式链到4下标的位置。如果我们又需要70字节,找到8下标,为空,池子里面没有水了,就再malloc 72x20x2个字节的内存块,注水,把池子分为一部分操作。

函数实现的解释

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
obj是一个联合体,类型成员
在这里插入图片描述
在这里插入图片描述
free_list
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第二适配器的代码实现

//第二级适配器 
enum { __ALIGN = 8};//起始块的大小,8的倍数 
enum { __MAX_BYTES = 128};//最大字节个数是128 
enum { __NFREELISTS = __MAX_BYTES / __ALIGN }; //自由链的大小是16template<bool threads,int ints>//是否是多线程 
class __default_alloc_template//默认空间配置器 
{
private:union obj//这个结构就是一个一个的块 {union obj * free_list_link;// 相当于next,链 char client_data[1];//客户 };
private:static obj * volatile free_list[__NFREELISTS];//从内存查,数组下标0 1 ... 15static char *start_free;//指向池子的开头 static char *end_free;//指向池子的结尾 static size_t heap_size;//累计从堆区申请的空间大小 static size_t ROUND_UP(size_t bytes)//变成8的倍数 {return (bytes + __ALIGN - 1) & ~(__ALIGN - 1);}static size_t FREELIST_INDEX(size_t bytes)//计算申请空间大小的对应块的大小,返回下标 {return (bytes + __ALIGN -1) / __ALIGN  - 1;}static char *chunk_alloc(size_t size,int &nobjs)//往池子里注水 {//                              16       20char *result = NULL;size_t total_bytes = size * nobjs; //总的大小 size_t bytes_left = end_free - start_free;//大小 if(bytes_left >= total_bytes) // 满足了20块{result = start_free;start_free = start_free + total_bytes;return result;}else if(bytes_left >= size) //不够20个块,看看能不能足够1块{nobjs = bytes_left / size;//新的块 total_bytes = size*nobjs; //新的大小 result = start_free;start_free = start_free + total_bytes;return result;}else//连一块都不够 {size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size>>4);//申请新的池子 if(bytes_left > 0)//剩下的但是不够的内存填充进去 {obj * volatile * my_free_list = free_list + FREELIST_INDEX(bytes_left);((obj*)start_free)->free_list_link = *my_free_list;*my_free_list = (obj*)start_free;}start_free = (char*)malloc(bytes_to_get);if(NULL == start_free)//通过malloc申请空间失败了 {obj * volatile * my_free_list = NULL;for(int i = size ; i <= __MAX_BYTES; i += __ALIGN )//每次加8,扫描 {my_free_list = free_list + FREELIST_INDEX(i);obj * p = *my_free_list;if(p != NULL)//不为空 {*my_free_list = p->free_list_link;start_free = (char*)p;end_free = start_free + i;return chunk_alloc(size,nobjs);//是原来池子上的内存 }}start_free = (char*)malloc_alloc::allocate(bytes_to_get);}end_free = start_free + bytes_to_get;heap_size += bytes_to_get;return chunk_alloc(size,nobjs);}}static void *refill(size_t n) //把池子里的空间拿出来进行分块,链起来, n byte num ; n % 8 == 0;{int nobjs = 20;char *chunk = chunk_alloc(n,nobjs);//注水20个块 if(1 == nobjs){return chunk;//?}obj * volatile * my_free_list = NULL;obj * result = (obj*)chunk;obj * current_obj = NULL, *next_obj = NULL;int i = 0;my_free_list = free_list + FREELIST_INDEX(n);*my_free_list = next_obj = (obj*)(chunk + n);for(i = 1; ; ++i){current_obj = next_obj;next_obj = (obj*)((char*)next_obj + n);if(i == nobjs - 1){current_obj->free_list_link = NULL;break;}current_obj->free_list_link = next_obj;}return result;}public:static void *allocate(size_t n)// 申请空间,n byte num;{if(n > (size_t)__MAX_BYTES)//大于128 {return malloc_alloc::allocate(n);//调用第一级适配器 }obj * volatile * my_free_list = NULL;//二级指针 obj * result = NULL;//一级指针 my_free_list = free_list + FREELIST_INDEX(n); result = *my_free_list;if(NULL == result){void *r = refill(ROUND_UP(n));// n 12 = 16return r;}*my_free_list = result->free_list_link;return result;}static void deallocate(void *p,size_t n)//释放空间 {if(n > (size_t) __MAX_BYTES){malloc_alloc::deallocate(p,n);return ;}obj *q = (obj*)p;//把块还回去 obj * volatile * my_free_list = free_list + FREELIST_INDEX(n);//12//16q->free_list_link = *my_free_list;*my_free_list = q;//把块链接起来 return ;} // malloc realloc , static void *reallocate(void *p,size_t old_sz,size_t new_sz)//追加空间 {if(old_sz > __MAX_BYTES && new_sz > __MAX_BYTES){return malloc_alloc::reallocate(p,old_sz,new_sz);}if(ROUND_UP(old_sz) == ROUND_UP(new_sz))// 12 14 // 16{return p;//足够了,不需要重新分配 }// old_sz < 128  new_sz < 128;//    >               <//   <                >size_t sz = old_sz < new_sz ? old_sz:new_sz;void *s = allocate(new_sz);//调动一级适配器 memmove(s,p,sz);deallocate(p,old_sz);//释放p return s;}
};
template<bool threads,int ints>
typename __default_alloc_template<threads,ints>::obj * volatile
__default_alloc_template<threads,ints>::free_list[__NFREELISTS]={NULL}; template<bool threads,int ints>
char * __default_alloc_template<threads,ints>::start_free = NULL;template<bool threads,int ints>
char * __default_alloc_template<threads,ints>::end_free = NULL;template<bool threads,int ints>
size_t __default_alloc_template<threads,ints>::heap_size = 0;

书写<stl_construct.h>

#ifndef YHP_CONSTRUCT_H
#define YHP_CONSTRUCT_H
#include"yhp_iterator.h"
#include"yhp_type_traits.h"
namespace yhp
{
template<class T1,class T2>
inline void construct(T1 *p,const T2 &val)//带参数的构造函数 
{new(p) T1(val);//构建对象并初始化,定位new 
}
template<class T>
inline void construct(T *p)//不带参数的构造函数 
{new(p)  T();
}template<class T>
inline void destroy(T *p)//销毁函数 
{p->~T();
}template<class _FI>
inline void destroy(_FI _F, _FI _L)
{__destroy(_F,_L,value_type(_F));
}
template<class _FI,class T>
inline void __destroy(_FI _F,_FI _L , T *)
{__type_traits<T>();typedef typename __type_traits<T>::has_trivial_destructor  dest;__destroy_aux(_F,_L,dest());
}
template<class _FI>
inline void __destroy_aux(_FI _F,_FI _L , __true_type)
{}template<class _FI>
inline void __destroy_aux(_FI _F,_FI _L , __false_type)
{for(; _F != _L; ++_F){destroy(&*_F);}
}}
#endif
http://www.lbrq.cn/news/2694565.html

相关文章:

  • 牛商网做网站怎么样app优化
  • 做高端网站的网络公司网站服务器搭建
  • 物流网络化seo网站排名优化公司
  • 深圳企业企业网站建设下载百度2023最新版安装
  • 网站后台安全密码seo的优化方案
  • 免费做网页的网站杭州百度快速排名提升
  • 做网站如何抓住客户的需求爱站工具
  • 1核2g 做网站北京网站seo
  • asp.net 做网站源代码深圳网站设计公司
  • 上传wordpress到lampseo怎么优化方法
  • 做网站和游戏是如何赚钱夫唯老师seo
  • 广州科技网站建设成都seo经理
  • 网站引导视频怎么做产品质量推广营销语
  • 做淘宝先在批发网站上拿货百度竞价投放
  • 陕西网站建设咨询网络运营具体做什么
  • 如何用dw做旅游网站目录网站权重怎么查
  • 盘古建站模板搜索引擎有哪些网站
  • wordpress网站打不开星巴克营销策划方案
  • 足球网页制作模板seo网络推广是什么意思
  • 专门做网站无锡seo网站管理
  • 平顶山公司做网站可以放友情链接的网站
  • 网站建设制作设计珠海企业网站推广优化
  • 做视频网站用什么模板网络营销典型案例
  • 厦门有什么网站制作公司黄页引流推广
  • 怎么用企业网站做营销电商运营培训大概多少学费
  • dreamweaver学生用哪个版本seo流量排名软件
  • xampp网站后台免费网站安全软件大全
  • WordPress已安装主题好口碑的关键词优化
  • 赤壁市建设工程造价信息价网站查询seo中介平台
  • 做网站免费推广网站排名
  • GitHub宕机时的协作方案
  • 【物联网】基于树莓派的物联网开发【26】——树莓派开启串口并配置串口助手Minicom
  • 【论文阅读】一种基于经典机器学习的肌电下肢意图检测方法,用于人机交互系统
  • 虚拟机一站式部署Claude Code 可视化UI界面
  • Wireshark专家模式定位网络故障:14种TCP异常深度解剖
  • 支持任意 MCP 协议的客户端