IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 实现一个简单的STL allocator -> 正文阅读

[C++知识库]实现一个简单的STL allocator

1. 概述

本文实现了一个简陋的allocator,并简单解释了new/delete的内部实现过程。

2. 一个简单的STL allocator

STL allocator是容器中的空间配置器,标准库默认的是std :: allocator。它的主要作用是内存分配与释放,对象构造和析构。它隐藏在容器内部,一般我们不需要关注,但了解其实现还是很有必要的。
实现的简陋allocator如下(详见参考文献1):

#ifndef MYALLOCATOR_H_
#define MYALLOCATOR_H_

#include <new>
#include <cstddef>
#include <cstdlib>
#include <climits>
#include <iostream>

namespace MA
{

template<typename T>
inline T* _allocate(ptrdiff_t size, T*)
{
    T* tmp = static_cast<T*>(::operator new(static_cast<size_t>(size * sizeof(T))));
    if(nullptr == tmp)
    {
        std::cerr << "out of memory" << std::endl;
    }

    return tmp;
}

template<typename T>
inline void _deallocate(T* buffer)
{
    ::operator delete(buffer);
}

template<typename T1, typename T2>
inline void _constructor(T1* p, const T2& value)
{
    new(p) T1(value);
}

template<typename T>
inline void _destroy(T* p)
{
    p->~T();
}

template<typename T>
struct allocator
{
    using value_type = T;
    using pointer = T*;
    using const_pointer = const T*;
    using reference = T&;
    using const_reference = const T&;
    using size_type = size_t;
    using difference_type = ptrdiff_t;

    template<typename U>
    struct rebind
    {
        using other = allocator<U>;
    };

    pointer allocate(size_type n, const void* hint = 0)
    {
        return _allocate(static_cast<difference_type>(n), static_cast<pointer>(nullptr));
    }

    void deallocate(pointer p, size_type n)
    {
        _deallocate(p);
    }

    void construct(pointer p, const T& value)
    {
        _constructor(p, value);
    }

    void destroy(pointer p)
    {
        _destroy(p);
    }

    pointer address(reference x)
    {
        return static_cast<pointer>(&x);
    }

    const_pointer const_address(const_reference x)
    {
        return static_cast<const_pointer>(&x);
    }

    size_type max_size() const
    {
        return static_cast<size_type>(UINT_MAX / sizeof(T));
    }
};

}

#endif /* MYALLOCATOR_H_ */

其中主要的接口及其作用如下:

  1. pointer allocate(size_type n, const void* hint = 0): 分配内存来存储n个类型为T的实例,并返回指向它的指针
  2. void deallocate(pointer p, size_type n): 释放分配的内存
  3. void construct(pointer p, const T& value): 使用p指向的value构造一个对象
  4. void destroy(pointer p): 调用p指向对象的析构函数

自定义allocator的使用如下(完整代码详见参考文献2):

#include "MyAllocator.h"
#include <vector>
#include "gtest/gtest.h"

struct MyAllocatorTest : testing::Test
{
};

TEST_F(MyAllocatorTest, test_for_my_allocator)
{
    int arr[3] {1, 2, 3};
    std::vector<int, MA::allocator<int>> vec{arr, arr + 3};
    ASSERT_EQ(1, vec[0]);
    ASSERT_EQ(2, vec[1]);
    ASSERT_EQ(3, vec[2]);
}

3. new/delete简析

其中涉及到了内存分配与释放,对象构造和析构,这就要解释下new/delete了。
new是C++内置的关键字,它主要做三件事:

  1. 调用对应的operator new操作符分配内存
  2. 调用对应的构造函数
  3. 返回构造对象类型的指针

delete是C++内置的关键字,它主要做两件事:

  1. 调用对应的析构函数
  2. 调用对应的operator delete操作符释放内存

下面采用一个例子说明:

string *p = new string("Hello");
equals to: 
void *memory = ::operator new(sizeof(string)); // 调用::operator new分配内存
string::string("Hello"); // 调用构造函数将字符串放到分配的内存 
string *p = static_cast<string*>(memory); // 使p指针指向新构造的对象
delete p;
equals to: 
p->string::~string("Hello"); // 调用析构函数
::operator delete(memory); // 调用::operator delete释放内存

4. 总结

本文通过一个简陋的allocator初探std::allocator的实现机制,能够对std::allocator有一个初步了解。当然这与实际的实现相差甚远,还需继续研究,更深入的剖析敬请期待。

5. 参考文献

  1. 侯捷,STL源码剖析
  2. https://github.com/mzh19940817/MyAllocator

欢迎大家批评指正、评论和转载(请注明源出处),谢谢!

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-02 11:09:57  更:2021-09-02 11:10:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 21:18:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计