浅谈C++ allocator内存管理(对比new的局限性)(转)
STL中,对内存管理的alloc的设计,迫使我去学习了allocator类。这里对allocator内存管理做了点笔记留给自己后续查阅。allocator类声明、定义于头文件<memory>中的std命名空间内。所以,应该有以下内容位于文件头部… #include <memory> using namespace std; 文章目录 1. 我们所知道的malloc和new 2. C++中new的局限性 3. 使用allocator将内存分配、对象构造分离开
1. 我们所知道的malloc和new 再此之前,我只知道两种开辟内存的方式。 其一,可以使用C语言的函数malloc、realloc、calloc开辟内存,举个例子: int* ptr = (int *)malloc(10 * sizeof(int)); /* 进行强制类型转换 */ 其二,可以使用C++方式开辟内存,比如: int* ptr = new int[10]; 对于,C风格的内存管理这里不做讨论。但是,对于C++的new风格,这里总结一下它的局限性。对于我个人来说,我一般写成这样new int[10](),也就是在最后加一对小括号,因为C++保证这样可以将int[10]中内存全部初始化为0。 2. C++中new的局限性 对于以上这一段话,有一个话题需要弄清楚的,就是——内存构造。 对C++的new而言,它首先会(1)分配内存,然后自动的完成(2)对象构造。这里可以用侯捷先生翻译的《深度探索C++对象模型》一书中的伪代码来表示new的过程: Point* heap = __new(sizeof(Point));//开辟内存 if (head != 0) { head->Point::Point();//对象构造(内存构造) } 注意,__new不表示new(它只是完成内存申请),以上整个伪代码过程为new所完成的功能。 正是因为new的这一连串的操作,造成了性能的下降。比如, auto p = new string[100]; for (int i = 0; i < 5; ++i){ p[i] = "balaba..."; } 实际上,我只需要5个string,而new把100个对象全部构造好了(每个string已经被初始化为空字符串,也就是"")。 然后,接着又将p[0-4]赋值为balaba… 也就是前面将p[0-4]赋值为空字符串的操作,变得毫无意义。 3. 使用allocator将内存分配、对象构造分离开 既然,new有它自身的局限性。对于性能要求极高的STL肯定是不会使用new的。好在有一个allocator类——它也是一个模板类,同时就是用来处理内存问题的。 allocator类将new的内存分配、对象构造,视作两个独立的过程,并由独立的函数负责。举个例子: allocator<char> str; char* base = str.allocate(10), *p = base; //内存分配 str.construct(p++, 'a'); //对象构造并初始化 str.construct(p++, 'b'); cout << base[0] << base[1]; 因为allocator是模板类,所以需要指定类型。接着,调用allocate(10)函数来分配内存(申请了10个char内存)。然后,使用construct函数构造base[0]这块内存,并赋以初值a。 这就将new内存分配、内存构造给分离开了。一切,都像我们看到的那样。 同样,将delete的过程也拆分了开来。这是必须的,我们不能用delete去释放allocate分配的内存。 str.destroy(--p); //销毁对象 str.destroy(--p); str.deallocate(base, 10); //释放内存 小结:如果要使用allocate返回的内存,那么就必须先construct构造它。否则,你后续的行为都是未定义的(造成的后果也是严重的)。 但是,有几个例外。它们是uninitialized_copy、uninitialized_copy_n、uninitialized_fill和uninitialized_fill_n。从名字就知道uninitialized(未初始化的),它们的参数必须指向的是未构造的内存,比如uninitialized_copy会在给定位置构造元素。 有兴趣可以阅读《动态内存管理allocator类C++ STL标准模板库vector实现》看看它们的用法。 ———————————————— 版权声明:本文为CSDN博主「qingdujun」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qingdujun/article/details/85224771
新战场:https://blog.csdn.net/Stephen___Qin