内存池的实现2 类专用的内存适配器

B类增加了嵌入指针

#include<new>
#include<ctime>
#include<iostream>
#include<cstdio>
class A
{
public:A() {printf("next=%p\n", next);};static void* operator new(size_t size);static void operator delete(void* phead);static int m_iCount;// 用于分配计数统计,每new一次 + 1static int m_iMallocCount;A* next;//用于统计ma11oc次数,每ma11oc一次+1
private:static A* m_FreePosi;// 总是指向一块可以分配出去的内存的首地址static int m_sTrunkCount;//一次分配多少倍该类的内存
};void* A::operator new(size_t size)
{//A ppoint =(A *)malloc(size);//不再用传统方式实现,而是用内存池实现//return ppoint;A* tmplink;if (m_FreePosi == nullptr){//为空,我们要申请内存,申请的是很大一块内存size_t realsize = m_sTrunkCount * size;//申请m_sTrunkCount这么多倍的内存m_FreePosi = reinterpret_cast<A*>(new char[realsize]); // 这是传统new, 调用底层tmplink = m_FreePosi;//把分配出来的这一大块内存链接起来,供后续使用for (; tmplink != &m_FreePosi[m_sTrunkCount - 1]; ++tmplink){tmplink->next = tmplink + 1;printf("%p\n", tmplink->next);}tmplink->next = nullptr;++m_iMallocCount;}tmplink = m_FreePosi;m_FreePosi = m_FreePosi->next;++m_iCount;return tmplink;
}
void A :: operator delete(void* phead)
{//free(phead);//不再用传统方式实现,针对内存池有特别的实现(static_cast <A*>(phead))->next = m_FreePosi;m_FreePosi = static_cast <A*>(phead);
}
int A::m_iCount = 0;
int A::m_iMallocCount = 0;
A* A::m_FreePosi = nullptr;
int A::m_sTrunkCount = 5;class B
{
private:struct obj {unsigned long mile;char type;};union{obj b;B* next;};public:unsigned long getMiles() { return b.mile; }char getType() { return b.type; }void set(unsigned long m, char t) {b.mile = m;b.type = t;}static void* operator new(size_t size);static void operator delete(void* phead);static int m_iCount;// 用于分配计数统计,每new一次 + 1static int m_iMallocCount;//用于统计ma11oc次数,每ma11oc一次+1
private:static B* m_FreePosi;// 总是指向一块可以分配出去的内存的首地址static int m_sTrunkCount;//一次分配多少倍该类的内存
};void* B::operator new(size_t size)
{B* p = m_FreePosi;if (p)	//如果p有效就把链表头部向下移m_FreePosi = p->next;else{//如果链表已空,申请一大块内存B* newBlock = static_cast<B*>(::operator new(m_sTrunkCount * sizeof(B)));//将小块穿成一个freelistfor (int i = 1; i < m_sTrunkCount - 1; ++i)newBlock[i].next = &newBlock[i + 1];newBlock[m_sTrunkCount - 1].next = 0;p = newBlock;m_FreePosi = &newBlock[1];}return p;
}void B :: operator delete(void* phead){//free(phead);//不再用传统方式实现,针对内存池有特别的实现(static_cast <B*>(phead))->next= m_FreePosi;m_FreePosi= static_cast <B*>(phead);}int B :: m_iCount =0;int B :: m_iMallocCount =0;B* B::m_FreePosi= nullptr;int B :: m_sTrunkCount =5;//一次分配5倍的该类内存作为内存池的大小class C{public:C();~C();private:};C::C(){}C::~C(){}int main8() {clock_t start, end,end2;start = clock();for (int i = 0; i < 5000000; ++i){B* pa = new B();//printf("%p\n", pa);//pa->set(i, i+'a');//std::cout << pa->getMiles() << pa->getType() << std::endl;}end = clock();for (int i = 0; i < 5000000; ++i){C* pa = new C();//printf("%p\n", pa);//pa->set(i, i+'a');//std::cout << pa->getMiles() << pa->getType() << std::endl;}end2 = clock();std::cout <<"使用内存池" << end - start << std::endl;std::cout << "不使用内存池" << end2 - end << std::endl;return 1;/*使用内存池322不使用内存池907*/}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/447079.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++学习 高级编程

C 文件和流 到目前为止&#xff0c;目前使用最为广泛的是 iostream 标准库&#xff0c;它提供了 cin 和 cout 方法分别用于从标准输入读取流和向标准输出写入流。以下将介绍从文件读取流和向文件写入流。这就需要用到 C 中另一个标准库 fstream&#xff0c;它定义了三个新的数…

内存池的实现3 固定大小的allocator单线程内存配置器

如果我们想使内存管理器用于其他大小不同的类该怎么办呢&#xff1f;为每一个类重复管理逻辑显然是对开发时间的不必要浪费。如果我们看一下前面内存管理器的实现&#xff0c;就会明显地看出内存管理逻辑实际上独立于特定的类 有关的是对象的大小一这是内存池模板实现的良好候选…

C++中文版本primer 第二章变量和基本类型 学习笔记

2.2变量 2.2.1 变量定义 列表初始化 定义一个名字为units_sold的int变量并初始化为0 int units_sold 0; int units_sold {0}; int units_sold{0}; int units_sold(0); C11 用花括号来初始化变量&#xff0c;上面这个步骤也称之为列表初始化。这种初始化有一个重要的特点&…

内存池中的嵌入式指针

嵌入式指针 可以union改struct 内存分配后 next指针就没用了 直接作为数据空间比较省内存 因为对指针指向的内存存储的时候 编译器是不管你是什么类型的 &#xff0c;这里有道练习题可以对指针的概念稍微理解一下&#xff1a; #include <iostream> using std::cout; us…

C++ 标准程序库std::string 详解

现在一般不再使用传统的char*而选用C标准程序库中的string类&#xff0c;是因为string标准程序和char*比较起来&#xff0c;不必担心内存是否足够、字符串长度等等&#xff0c;而且作为一个类出现&#xff0c;集成的操作函数足以完成大多数情况下(甚至是100%)的需要。比如&…

内存池的实现4 alloc内存池

alloc 内存池 优点: &#xff1a;本质是定长内存池的改进&#xff0c;分配和释放的效率高。可以解决一定长度内存分配的问题。 缺点 &#xff1a;存在内碎片的问题&#xff0c;且将一块大内存切小以后&#xff0c;申请大内存无法使用&#xff0c;别的FreeList挂了很多空闲的内存…

C++primer第15章节详解面向对象程序设计

前言 面向程序设计基于三个基本概念&#xff1a;数据抽象、继承和动态绑定。继承和动态绑定可以使得程序定义与其他类相似但是不完全相同的类&#xff1b;使用彼此相似的类编写程序时候&#xff0c;可以在一定程度上忽略掉他们的区别。 OOP概述 oop&#xff08;面向程序的设…

内存池的线程安全问题

malloc/free 据说老版本libc 有俩个版本&#xff0c;当你连接 pthread库的时候它就链接的是线程安全版&#xff0c;否则不是。在glic 2.2 以上无论怎么都是线程安全的。 new/delete new/delete 封装的 malloc/free , 如果malloc/free 是它们就是线程安全的。

C++11命名空间的using说明

std::cin 表示从标准输入读取内容&#xff0c;此处的作用域操作符::是指编译器应该从左侧名字所示的作用域中寻找右侧那个名字。因此std::sin表示使用命名空间std中的cin。 每个名字都需要有独立的using的声明 每一个using声明引入命名空间中的一个成员&#xff0c;比如可以将…

c语音的一些特殊关键字

PRETTY_FUNCTION C语言中获取函数名 C语言中的__LINE__用以指示本行语句在源文件中的位置信息

C++ primer三章二节标准库类型string

标准库类型string 标准库类型string表示可变长的字符序列&#xff0c;使用#include<string>引入头文件&#xff0c;string定义在命名空间std中。 定义和初始化string对象 如何初始化类的对象是由类的本身决定的&#xff0c;类可以定义很多初始化对象的方式&#xff0c;…

vim 不常见但好用的命令

● 跳跃 ○ 向前跳跃是 f ○ 向后跳跃是 F ● 继续 ○ 保持方向是 ; ○ 改变方向是 , ● 可以加上 [count] 来加速 ● ^ 是到本行第一个非空字符 ● 0 是到本行第一个字符&#xff0c;不管是不是空格 ● g_ 是到本行最后一个非空字符 ● 两个按键要依次按下 ● $ 跳到本行最后…

加密机组会 会议纪要

2020年9月28日 1&#xff0c;使用基类继承的机制&#xff0c;调用写好的函数接口 1&#xff0c;不要 使用Content&#xff08;封装数据&#xff0c;本质是一个json字符串&#xff09;&#xff0c;1&#xff0c;因为每次使用这个需要对里面的内容进行序列化&#xff0c;转化成…

c++为什么没有垃圾回收

垃圾回收 内存清理的另一个方面是垃圾回收。在支持垃圾回收的环境中&#xff0c;程序员几乎不必显式地释放与对象关联的 内存。运行时库会在某时刻自动清理没有任何引用的对象。 与C#和Java不一样&#xff0c;在C语言中没有内建垃圾回收。在现代C中&#xff0c;使用智能指针管理…

C++ Vecctor容器浅析

Vector的定义 向量&#xff08;Vector&#xff09;是一个封装了动态大小数组的顺序容器&#xff08;Sequence Container&#xff09;。跟任意其它类型容器一样&#xff0c;它能够存放各种类型的对象。可以简单的认为&#xff0c;向量是一个能够存放任意类型的动态数组。vector…

C++primer第二章2.4节对于const限定符相关内容进行详解

const限定符 const对象一旦创建后其数值就不会被再次改变&#xff0c;因此const对象必须初始化。const对象只在文件中有效在不同的文件中使用不同的const来定义不同的常量&#xff0c;那么每个文件定义的变量只会在自己所属的文件中有效。如果想让多个文件共享同一个const变量…

二分法的常见问题

mid(leftright)/2; mid (high - low) / 2 low; 这样写可以防止left right溢出 ,不过数足够大是时候该溢还是溢 为什么要取右边中间数呢&#xff1f;这是因为在区间里 只有 2 个元素的时候&#xff0c;把[left…right]划分成[left…mid - 1]和[mid…right]这两个区间&#x…

演示IPFS的一个完整的流程以及针对部分概念的详解

整体的流程 1&#xff0c;创建ipfs节点 通过ipfs init在本地计算机建立一个IPFS节点本文有些命令已经执行过了&#xff0c;就没有重新初始化。部分图片拷贝自先前文档&#xff0c;具体信息应以实物为准 $ ipfs init initializing IPFS node at /Users/CHY/.ipfs generating 2…

c++ 算法的时间复杂度

一般ACM或者笔试题的时间限制是1秒或2秒。 在这种情況下&#xff0c;C代码中的操作次数控制在 10^7为最佳。 下面给出在不同数据范国下&#xff0c;代码的时间复杂度和算法该如何选择&#xff1a; 1.n≤ 30,指数级别&#xff0c;dis剪枝&#xff0c;状态压缩dp 2.n < 100 &g…

简单工厂模式实现计算器

#include <iostream> #include <vector> #include <string> #include <iostream> #include <map> using namespace std; #define __THROW_ZERO do {cerr << "The dividend is 0" << endl; exit(1);}while(0);/* 简单工厂处…