栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

258-C++ STL SGI标准的空间配置器alloc

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

258-C++ STL SGI标准的空间配置器alloc

1.POD类型是只包含数据的结构体类型,没有方法,把它看作是一个数据集合时,就是POD类型

2.对于内置类型来说,没有拷贝构造函数和析构函数

3.#include 负责空间的申请和释放
#include 负责对象的构建和析构
#include 负责处理大块内存的填充和拷贝

4.STL把建立对象和析构对象分成一组,申请空间和释放空间分成一组

5.对象建立前的空间配置,和对象析构之后的空间释放,由#include 负责,它的设计理念如下:
①向系统的堆区申请空间
②考虑多线程的情况
③考虑内存不足的情况
④考虑小块能存可能造成内存碎片的情况

6.new在申请失败时会抛出异常,malloc在申请失败时返回空指针(0指针)

7.SGI设计了双极配置器,第一级配置器直接使用malloc和free,第二级配置器则按情况采取不同的策略,如果内存块大于128字节,则视为足够大,就使用一级配置器,如果内存块小于128字节,则视为足够小,则采用内存池方式,而不再求助于第一级配置器,

8.堆区分为两个部分,一个是小块内存存取,一个是大块内存存取,就是说如果开辟的少,就从小块内存中存取,如果开辟的比较大,就从大块的内存中存取

9.堆区的管理方式和一级配置器二级配置器是完全一样的,没有什么区别

10.二级配置器称为默认配置器,如果申请的空间小于128字节,就从内存池中取,如果申请的空间大于128,就调动一级配置器

所以如果开放二级配置器也是有可能转到一级配置器的

11.定义一个list,list mylist;然后插入了一些数据,现在执行mylist.pop_back();删除节点,那么删除完后,这个节点的空间是否返回给系统了呢?

答案:在STL中,内存池分为两级,在申请节点的时候,如果申请节点的大小小于等于128字节,它是从二级配置中的内存池中分配的空间,那么释放完以后就会把空间还给内存池,并没有返还给堆区,如果申请节点的时候,申请节点的大小大于128字节,那么释放完以后,就会把空间还给内存池

12.定义一个vector,在pop_back()后,会把空间还给堆区吗?

答案:不会,vector是连续分配空间的,如果空间大小小于等于128,是从内存池中分配空间,尽管pop_back()了,但是仍然不会把空间换个内存池,只有当对象死亡的时候,才会把整个vector的空间还给内存池,如果空间大小大于128,就还给堆区

13.一级配置器__malloc_alloc_template剖析

14.静态成员初始化,静态函数指针初始化,静态变量初始化

15.一级配置器处理内存不足的核心思想,假设在申请空间之前,已经申请了一块很大的空间,当申请空间的时候,如果空间足够,则正常分配空间,如果空间不足,判断之前申请的空间是否为空,即是否还存在,如果存在,就把之前申请的很大的空间释放掉,然后将指向该空间的指针置为null,表示该空间已经释放掉了,如果这时空间够了,则分配空间,如果判断之前申请的空间不存在,则打印出错误或者什么,有自己来定义

16.二级配置器多了一些机制,避免太小的内存块造成内存泄露的问题,小的内存块带来的不仅仅是内存碎片的问题,配置时也带来了额外的负担,负担永远无法避免,如果申请的空间越小,额外负担所占的比例就越大,空间浪费就越大

17.当malloc(1)的时候,并不意味着就从内存中分配1字节的空间,上面是有4个字节的上越界标记,下面也有4个字节的下越界标记,上面还有一个信息的头部,头部中有一个值记录的当时申请了多大的空间,还有next域和pre域,连接到链表中,在上面或者下面还有一个标记(在不同的系统位置不一样),标记是否释放,释放的时候看如果没有释放,那就释放,如果已经释放了,就不释放了

所以,申请的空间越小,这些额外的负担也就占的越大

malloc函数在调用的时候,速度太慢了,这就导致我们要使用内存池,要消去这些额外的负担,加快申请空间的速度

18.为了方便管理,SGI二级配置器将任何小块内存都上调至8个倍数

加入申请了10号区域的内存块,它就把10号区域的链表从头删除一个节点交给用户,释放的时候再还回来

012…15每个都是一个指针

每个区域的块与块之间是通过free_list_link链接起来的

分配块的时候是头删,归还块的时候是头插

19.volatile关键字

20.reallocate必须要会,处理的方法很巧妙

21.引用是指针的语法糖,lambda表达式是仿函数的语法糖

加入要通过函数修改变量a的值,如果使用指针,则需要在函数内部进行指针判空的操作,而如果使用引用的方式,则不要进行判空操作,所以引用是指针的语法糖

fun(int* p)
{
	if(p != NULL)
	{
		*p += 10;
	}
}
fun(int& p)
{
	p += 10;
}
int main()
{
	int a = 0;
	//fun(&a);
	fun(a);
	return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/769204.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号