iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++中std::allocator的使用案例详解
  • 760
分享到

C++中std::allocator的使用案例详解

2024-04-02 19:04:59 760人浏览 薄情痞子
摘要

标准库中包含一个名为allocator的类,允许我们将分配和初始化分离。使用allocator通常会提供更好的性能和更灵活的内存管理能力。    

标准库中包含一个名为allocator的类,允许我们将分配和初始化分离。使用allocator通常会提供更好的性能和更灵活的内存管理能力。

        new有一些灵活性上的局限,其中一方面表现在它将内存分配和对象构造组合在了一起。类似的,delete将对象析构和内存释放组合在了一起。我们分配单个对象时,通常希望将内存分配和对象初始化组合在一起。因为在这种情况下,我们几乎肯定知道对象应有什么值。当分配一大块内存时,我们通常计划在这块内存上按需构造对象。在此情况下,我们希望将内存分配和对象构造分离。这意味着我们可以分配大块内存,但只在真正需要时才真正执行对象的创建操作(同时付出一定开销)。一般情况下,将内存分配和对象构造组合在一起可能会导致不必要的浪费

        标准库allocator类定义在头文件memory中,它帮助我们将内存分配和对象构造分离开来它提供一种类型感知的内存分配方法,它分配的内存是原始的、未构造的。类似vector,allocator是一个模板。为了定义一个allocator对象,我们必须指明这个allocator可以分配的对象类型。当一个allocator对象分配内存时,它会根据给定的对象类型来确定恰当的内存大小和对齐位置。allocator支持的操作,如下:

        allocatro分配的内存是未构造的(unconstructed)。我们按需要在此内存中构造对象。在新标准库中,construct成员函数接受一个指针和零个或多个额外参数,在给定位置构造一个元素。额外参数用来初始化构造的对象。类似make_shared的参数,这些额外参数必须是与构造的对象的类型相匹配的合法的初始化器。

        在早期版本的标准库中,construct只接受两个参数:指向创建对象位置的指针和一个元素类型的值。因此,我们只能将一个元素拷贝到未构造空间中,而不能用元素类型的任何其它构造函数来构造一个元素。还未构造对象的情况下就使用原始内存是错误的。为了使用allocator返回的内存,我们必须用construct构造对象。使用未构造的内存,其行为是未定义的。

        当我们用完对象后,必须对每个构造的元素调用destroy来销毁它们。函数destroy接受一个指针,对执行的对象执行析构函数。我们只能对真正构造了的元素进行destroy操作。一旦元素被销毁后,就可以重新使用这部分内存来保存其它string,也可以将其归还给系统。释放内存通过调用deallocate来完成。我们传递给deallocate的指针不能为空,它必须指向由allocate分配的内存。而且,传递给deallocate的大小参数必须与调用allocate分配内存时提供的大小参数具有一样的值。

        标准库还为allocator类定义了两个伴随算法,可以在未初始化内存中创建对象。它们都定义在头文件memory中,如下:

        在c++中,内存是通过new表达式分配,通过delete表达式释放的。标准库还定义了一个allocator类来分配动态内存块。分配动态内存的程序应负责释放它所分配的内存。内存的正确释放是非常容易出错的地方:要么内存永远不会被释放,要么在仍有指针引用它时就被释放了。新的标准库定义了智能指针类型------shared_ptr、unique_ptr和weak_ptr,可令动态内存管理更为安全。对于一块内存,当没有任何用户使用它时,智能指针会自动释放它。现代C++程序应尽可能使用智能指针。

        std::allocator是标准库容器的默认内存分配器。你可以替换自己的分配器,这允许你控制标准容器分配内存的方式。

        以上内容主要摘自:《C++Primer(Fifth Edition 中文版)》第12.2.2章节

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:


#include "allocator.hpp"
#include <iOStream>
#include <memory>
#include <string>
#include <vector>
 
namespace allocator_ {
 
 
// reference: C++ Primer(Fifth Edition) 12.2.2
int test_allocator_1()
{
	std::allocator<std::string> alloc; // 可以分配string的allocator对象
	int n{ 5 };
	auto const p = alloc.allocate(n); // 分配n个未初始化的string
 
	auto q = p; // q指向最后构造的元素之后的位置
	alloc.construct(q++); // *q为空字符串
	alloc.construct(q++, 10, 'c'); // *q为cccccccccc
	alloc.construct(q++, "hi"); // *q为hi
 
	std::cout << *p << std::endl; // 正确:使用string的输出运算符
	//std::cout << *q << std::endl; // 灾难:q指向未构造的内存
	std::cout << p[0] << std::endl;
	std::cout << p[1] << std::endl;
	std::cout << p[2] << std::endl;
 
	while (q != p) {
		alloc.destroy(--q); // 释放我们真正构造的string
	}
 
	alloc.deallocate(p, n);
 
	return 0;
}
 
int test_allocator_2()
{
	std::vector<int> vi{ 1, 2, 3, 4, 5 };
 
	// 分配比vi中元素所占用空间大一倍的动态内存
	std::allocator<int> alloc;
	auto p = alloc.allocate(vi.size() * 2);
	// 通过拷贝vi中的元素来构造从p开始的元素
	
	auto q = std::uninitialized_copy(vi.begin(), vi.end(), p);
	// 将剩余元素初始化为42
	std::uninitialized_fill_n(q, vi.size(), 42);
 
	return 0;
}
 
 
// reference: Http://www.modernescpp.com/index.PHP/memory-management-with-std-allocator
int test_allocator_3()
{
	std::cout << std::endl;
 
	std::allocator<int> intAlloc;
 
	std::cout << "intAlloc.max_size(): " << intAlloc.max_size() << std::endl;
	int* intArray = intAlloc.allocate(100);
 
	std::cout << "intArray[4]: " << intArray[4] << std::endl;
 
	intArray[4] = 2011;
 
	std::cout << "intArray[4]: " << intArray[4] << std::endl;
 
	intAlloc.deallocate(intArray, 100);
 
	std::cout << std::endl;
 
	std::allocator<double> doubleAlloc;
	std::cout << "doubleAlloc.max_size(): " << doubleAlloc.max_size() << std::endl;
 
	std::cout << std::endl;
 
	std::allocator<std::string> stringAlloc;
	std::cout << "stringAlloc.max_size(): " << stringAlloc.max_size() << std::endl;
 
	std::string* myString = stringAlloc.allocate(3);
 
	stringAlloc.construct(myString, "Hello");
	stringAlloc.construct(myString + 1, "World");
	stringAlloc.construct(myString + 2, "!");
 
	std::cout << myString[0] << " " << myString[1] << " " << myString[2] << std::endl;
 
	stringAlloc.destroy(myString);
	stringAlloc.destroy(myString + 1);
	stringAlloc.destroy(myString + 2);
	stringAlloc.deallocate(myString, 3);
 
	std::cout << std::endl;
 
	return 0;
}
 
//
// reference: http://en.cppreference.com/w/cpp/memory/allocator
int test_allocator_4()
{
	std::allocator<int> a1;   // default allocator for ints
	int* a = a1.allocate(1);  // space for one int
	a1.construct(a, 7);       // construct the int
	std::cout << a[0] << '\n';
	a1.deallocate(a, 1);      // deallocate space for one int
 
	// default allocator for strings
	std::allocator<std::string> a2;
 
	// same, but obtained by rebinding from the type of a1
	decltype(a1)::rebind<std::string>::other a2_1;
 
	// same, but obtained by rebinding from the type of a1 via allocator_traits
	std::allocator_traits<decltype(a1)>::rebind_alloc<std::string> a2_2;
 
	std::string* s = a2.allocate(2); // space for 2 strings
 
	a2.construct(s, "foo");
	a2.construct(s + 1, "bar");
 
	std::cout << s[0] << ' ' << s[1] << '\n';
 
	a2.destroy(s);
	a2.destroy(s + 1);
	a2.deallocate(s, 2);
 
	return 0;
}
 
} // namespace allocator_

GitHub: https://GitHub.com/fengbinGChun/Messy_Test 

到此这篇关于C++中std::allocator的使用案例详解的文章就介绍到这了,更多相关C++中std::allocator的使用内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++中std::allocator的使用案例详解

本文链接: https://www.lsjlt.com/news/134941.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++中std::allocator的使用案例详解
    标准库中包含一个名为allocator的类,允许我们将分配和初始化分离。使用allocator通常会提供更好的性能和更灵活的内存管理能力。    ...
    99+
    2024-04-02
  • C++中allocator类使用示例
    目录动态内存管理StrVec类实现细节总结动态内存管理 之前我们讲述过动态内存的开辟,可以通过new, malloc,以及alloc等方式,本文通过介绍alloc方式,构造一个Str...
    99+
    2024-04-02
  • C++11std::function和std::bind的使用示例详解
    目录概述可调用对象std::functionstd::function函数原型std::function的主要作用std::function的优缺点std::bindstd::bin...
    99+
    2023-03-19
    C++11 std::function和std::bind C++11 std::function和std::bind使用
  • C++11 中的std::function和std::bind详解
    目录1. 可调用对象2. std::function3. std::bind3.1 std::bind绑定普通函数3.2 std::bind绑定一个成员函数3.3 绑定一个引用参数4...
    99+
    2024-04-02
  • C++20中的std::span详解
    span就是一个连续对象存储的观察者。类似std::string_view是string的观察者。连续的存储,不一定是数组。例如: zero(char (&arr)...
    99+
    2023-03-06
    C++20 std::span C++ std
  • C++ std::function的用法详解
    类模版std::function是一种通用、多态的函数封装。std::function的实例可以对任何可以调用的目标实体进行存储、复制、和调用操作,这些目标实体包括普通函数、Lamb...
    99+
    2024-04-02
  • C# log4net使用案例详解
    这边先介绍简单的使用:在控制台输出和写入文件 首先添加log4net的nuget包 然后在app.config中添加配置项==configSections只能有一个,且是config...
    99+
    2024-04-02
  • C# AttributeUsage使用案例详解
    C# AttributeUsage的使用是如何的呢?首先让我们来了解一下什么是AttributeUsage类它是另外一个预定义特性类,AttributeUsage类的作用就是帮助我们...
    99+
    2024-04-02
  • C# PropertyGrid使用案例详解
    1. 只有public的property能显示出来,可以通过BrowsableAttribute来控制是否显示,通过CategoryAttribute设置分类,通过Descripti...
    99+
    2024-04-02
  • C++11中std::function与std::bind的用法实例
    目录关于std::function 的用法:关于std::bind 的用法:附:std::function与std::bind双剑合璧总结关于std::function 的用法: 其...
    99+
    2024-04-02
  • C++ std::bind用法详解
    一、介绍 C++11中提供了std::bind。bind()函数的意义就像它的函数名一样,是用来绑定函数调用的某些参数的。 bind的思想实际上是一种延迟计算的思想,将可调用对象保存...
    99+
    2024-04-02
  • C++STL标准库std::vector的使用详解
    目录1. 简介2. 使用示例3. 构造、析构、赋值3.1 std::vector::vector 构造函数3.2 std::vector::~vector 析构函数3.3 std::...
    99+
    2024-04-02
  • 详解C++语言中std::array的神奇用法
    目录概述自动推导数组大小用函数返回std::array编译期字面量数值合法性校验编译期生成数组截取子数组拼接多个数组编译期拼接字符串展望C++20——打破更多的枷锁尾注概述 std:...
    99+
    2024-04-02
  • C++11中std::function基础用法详解
    目录一、std::function基本介绍二、进阶使用方法2.1 与智能指针相结合2.2 存储成员函数指针2.3 存储std::bind三、注意tipsstd::function是C...
    99+
    2023-05-18
    C++11 std::function用法 C++11 std::function C++ std::function
  • C++中inline用法案例详解
    1 引入inline关键字的原因 在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数,栈空间就是指放置程序的局...
    99+
    2024-04-02
  • C++ LARGE_INTEGER解析与使用案例详解
    这里解释前面碰到的LARGE_INTEGER结构。与可能的误解不同,64位数据并非要在64位操作系统下才能使用。在VC中,64位数据的类型为__int64。定义写法如下: ...
    99+
    2024-04-02
  • 深入解析C++中的std::thread的使用
    目录std::thread简介一、C++11 线程创建二、std::thread 的构造函数中接收什么参数?三、std::thread 的搭配用法std::thread简介 C++1...
    99+
    2023-05-16
    C++ std::thread使用 C++ std::thread用法 C++ std::thread
  • C# ThreadPool之QueueUserWorkItem使用案例详解
    先看代码: //设置可以同时处于活动状态的线程池的请求数目。 bool pool = ThreadPool.SetMaxThreads(8, 8); if (pool) { ...
    99+
    2024-04-02
  • C++中std::conditional如何使用
    本篇内容介绍了“C++中std::conditional如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!std::conditiona...
    99+
    2023-07-02
  • C++编程之 std::forward使用例子
    std::forward 是一个 C++11 中的模板函数,其主要作用是在模板函数或模板类中,将一个参数以“原样”(forward)的方式转发给另一个函数。通...
    99+
    2023-03-19
    C++ std::forward C++ std::forward使用
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作