STL源码学习笔记


  • 空间分配器

    为对象分配数据空间的一种工具,类似智能指针,负责空间的分配和释放

    所有容器的工作都离不开空间分配器

  • 手写一个内存分配器


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

    namespace my_allocator {
       template<typename T>
       inline T *_allocate(ptrdiff_t size, T *) {
           std::set_new_handler(nullptr);
           T *tmp = static_cast<T *>(::operator new(static_cast<size_t>(size * sizeof(T)))); // 调用全局的new分配空间
           if (tmp == nullptr) {
               std::cerr << "out of memory" << std::endl;
               exit(EXIT_SUCCESS);
          }
           return tmp;
      }

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

       template<typename T, typename U>
       inline void _construct(T *p, const U &value) {
           new(p) T{value}; // T(value)
      }

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

       template<typename T>
       class allocator {
       public:
           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 = nullptr) {
               return _allocate(static_cast<difference_type>(n), static_cast<pointer>(0));
          }

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

           void construct(pointer p, const_reference value) {
               _construct(p, value);
          }

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

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

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

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