|
|
|
@ -1,208 +1,207 @@
|
|
|
|
|
#ifndef MYTINYSTL_MEMORY_H_
|
|
|
|
|
#ifndef MYTINYSTL_MEMORY_H_ // 防止头文件被重复包含
|
|
|
|
|
#define MYTINYSTL_MEMORY_H_
|
|
|
|
|
|
|
|
|
|
// 这个头文件负责更高级的动态内存管理
|
|
|
|
|
// 包含一些基本函数、空间配置器、未初始化的储存空间管理,以及一个模板类 auto_ptr
|
|
|
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <climits>
|
|
|
|
|
#include <cstddef> // 标准定义,包含 size_t, ptrdiff_t 等类型定义
|
|
|
|
|
#include <cstdlib> // 标准库,包含 malloc, free 等函数
|
|
|
|
|
#include <climits> // 限制,包含 INT_MAX 等定义
|
|
|
|
|
|
|
|
|
|
#include "algobase.h"
|
|
|
|
|
#include "allocator.h"
|
|
|
|
|
#include "construct.h"
|
|
|
|
|
#include "uninitialized.h"
|
|
|
|
|
#include "algobase.h" // 算法基础,包含算法需要的一些基本工具
|
|
|
|
|
#include "allocator.h" // 分配器,提供内存分配和释放的功能
|
|
|
|
|
#include "construct.h" // 构造和析构,提供对象的构造和析构功能
|
|
|
|
|
#include "uninitialized.h" // 未初始化内存,提供未初始化内存的构造和析构功能
|
|
|
|
|
|
|
|
|
|
namespace mystl
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// 获取对象地址
|
|
|
|
|
template <class Tp>
|
|
|
|
|
constexpr Tp* address_of(Tp& value) noexcept
|
|
|
|
|
{
|
|
|
|
|
return &value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取 / 释放 临时缓冲区
|
|
|
|
|
// 获取对象地址
|
|
|
|
|
template <class Tp>
|
|
|
|
|
constexpr Tp* address_of(Tp& value) noexcept
|
|
|
|
|
{
|
|
|
|
|
return &value;
|
|
|
|
|
}
|
|
|
|
|
// 该函数模板返回对象的地址,是 C++11 引入的 std::addressof 的一个实现。
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
pair<T*, ptrdiff_t> get_buffer_helper(ptrdiff_t len, T*)
|
|
|
|
|
{
|
|
|
|
|
if (len > static_cast<ptrdiff_t>(INT_MAX / sizeof(T)))
|
|
|
|
|
len = INT_MAX / sizeof(T);
|
|
|
|
|
while (len > 0)
|
|
|
|
|
{
|
|
|
|
|
T* tmp = static_cast<T*>(malloc(static_cast<size_t>(len) * sizeof(T)));
|
|
|
|
|
if (tmp)
|
|
|
|
|
return pair<T*, ptrdiff_t>(tmp, len);
|
|
|
|
|
len /= 2; // 申请失败时减少 len 的大小
|
|
|
|
|
}
|
|
|
|
|
return pair<T*, ptrdiff_t>(nullptr, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t len)
|
|
|
|
|
{
|
|
|
|
|
return get_buffer_helper(len, static_cast<T*>(0));
|
|
|
|
|
}
|
|
|
|
|
// 获取 / 释放 临时缓冲区
|
|
|
|
|
template <class T>
|
|
|
|
|
pair<T*, ptrdiff_t> get_buffer_helper(ptrdiff_t len, T*)
|
|
|
|
|
{
|
|
|
|
|
if (len > static_cast<ptrdiff_t>(INT_MAX / sizeof(T)))
|
|
|
|
|
len = INT_MAX / sizeof(T); // 检查 len 是否超出 T 类型能表示的最大数量
|
|
|
|
|
while (len > 0)
|
|
|
|
|
{
|
|
|
|
|
T* tmp = static_cast<T*>(malloc(static_cast<size_t>(len) * sizeof(T))); // 分配内存
|
|
|
|
|
if (tmp)
|
|
|
|
|
return pair<T*, ptrdiff_t>(tmp, len); // 分配成功,返回内存和长度
|
|
|
|
|
len /= 2; // 申请失败时减少 len 的大小
|
|
|
|
|
}
|
|
|
|
|
return pair<T*, ptrdiff_t>(nullptr, 0); // 所有申请尝试都失败,返回空指针和长度 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t len, T*)
|
|
|
|
|
{
|
|
|
|
|
return get_buffer_helper(len, static_cast<T*>(0));
|
|
|
|
|
}
|
|
|
|
|
template <class T>
|
|
|
|
|
pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t len)
|
|
|
|
|
{
|
|
|
|
|
return get_buffer_helper(len, static_cast<T*>(0)); // 获取临时缓冲区,使用长度 len
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
void release_temporary_buffer(T* ptr)
|
|
|
|
|
{
|
|
|
|
|
free(ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
|
// 类模板 : temporary_buffer
|
|
|
|
|
// 进行临时缓冲区的申请与释放
|
|
|
|
|
template <class ForwardIterator, class T>
|
|
|
|
|
class temporary_buffer
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
ptrdiff_t original_len; // 缓冲区申请的大小
|
|
|
|
|
ptrdiff_t len; // 缓冲区实际的大小
|
|
|
|
|
T* buffer; // 指向缓冲区的指针
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 构造、析构函数
|
|
|
|
|
temporary_buffer(ForwardIterator first, ForwardIterator last);
|
|
|
|
|
|
|
|
|
|
~temporary_buffer()
|
|
|
|
|
{
|
|
|
|
|
mystl::destroy(buffer, buffer + len);
|
|
|
|
|
free(buffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
ptrdiff_t size() const noexcept { return len; }
|
|
|
|
|
ptrdiff_t requested_size() const noexcept { return original_len; }
|
|
|
|
|
T* begin() noexcept { return buffer; }
|
|
|
|
|
T* end() noexcept { return buffer + len; }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void allocate_buffer();
|
|
|
|
|
void initialize_buffer(const T&, std::true_type) {}
|
|
|
|
|
void initialize_buffer(const T& value, std::false_type)
|
|
|
|
|
{ mystl::uninitialized_fill_n(buffer, len, value); }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
temporary_buffer(const temporary_buffer&);
|
|
|
|
|
void operator=(const temporary_buffer&);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 构造函数
|
|
|
|
|
template <class ForwardIterator, class T>
|
|
|
|
|
temporary_buffer<ForwardIterator, T>::
|
|
|
|
|
temporary_buffer(ForwardIterator first, ForwardIterator last)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
len = mystl::distance(first, last);
|
|
|
|
|
allocate_buffer();
|
|
|
|
|
if (len > 0)
|
|
|
|
|
template <class T>
|
|
|
|
|
pair<T*, ptrdiff_t> get_temporary_buffer(ptrdiff_t len, T*)
|
|
|
|
|
{
|
|
|
|
|
initialize_buffer(*first, std::is_trivially_default_constructible<T>());
|
|
|
|
|
return get_buffer_helper(len, static_cast<T*>(0)); // 重载版本,带类型提示
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
free(buffer);
|
|
|
|
|
buffer = nullptr;
|
|
|
|
|
len = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// allocate_buffer 函数
|
|
|
|
|
template <class ForwardIterator, class T>
|
|
|
|
|
void temporary_buffer<ForwardIterator, T>::allocate_buffer()
|
|
|
|
|
{
|
|
|
|
|
original_len = len;
|
|
|
|
|
if (len > static_cast<ptrdiff_t>(INT_MAX / sizeof(T)))
|
|
|
|
|
len = INT_MAX / sizeof(T);
|
|
|
|
|
while (len > 0)
|
|
|
|
|
{
|
|
|
|
|
buffer = static_cast<T*>(malloc(len * sizeof(T)));
|
|
|
|
|
if (buffer)
|
|
|
|
|
break;
|
|
|
|
|
len /= 2; // 申请失败时减少申请空间大小
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
|
// 模板类: auto_ptr
|
|
|
|
|
// 一个具有严格对象所有权的小型智能指针
|
|
|
|
|
template <class T>
|
|
|
|
|
class auto_ptr
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
typedef T elem_type;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
T* m_ptr; // 实际指针
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 构造、复制、析构函数
|
|
|
|
|
explicit auto_ptr(T* p = nullptr) :m_ptr(p) {}
|
|
|
|
|
auto_ptr(auto_ptr& rhs) :m_ptr(rhs.release()) {}
|
|
|
|
|
template <class U>
|
|
|
|
|
auto_ptr(auto_ptr<U>& rhs) : m_ptr(rhs.release()) {}
|
|
|
|
|
|
|
|
|
|
auto_ptr& operator=(auto_ptr& rhs)
|
|
|
|
|
{
|
|
|
|
|
if (this != &rhs)
|
|
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
|
void release_temporary_buffer(T* ptr)
|
|
|
|
|
{
|
|
|
|
|
delete m_ptr;
|
|
|
|
|
m_ptr = rhs.release();
|
|
|
|
|
free(ptr); // 释放临时缓冲区
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
template <class U>
|
|
|
|
|
auto_ptr& operator=(auto_ptr<U>& rhs)
|
|
|
|
|
{
|
|
|
|
|
if (this->get() != rhs.get())
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
|
// 类模板 : temporary_buffer
|
|
|
|
|
// 进行临时缓冲区的申请与释放
|
|
|
|
|
template <class ForwardIterator, class T>
|
|
|
|
|
class temporary_buffer
|
|
|
|
|
{
|
|
|
|
|
delete m_ptr;
|
|
|
|
|
m_ptr = rhs.release();
|
|
|
|
|
private:
|
|
|
|
|
ptrdiff_t original_len; // 缓冲区申请的大小
|
|
|
|
|
ptrdiff_t len; // 缓冲区实际的大小
|
|
|
|
|
T* buffer; // 指向缓冲区的指针
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 构造、析构函数
|
|
|
|
|
temporary_buffer(ForwardIterator first, ForwardIterator last);
|
|
|
|
|
|
|
|
|
|
~temporary_buffer()
|
|
|
|
|
{
|
|
|
|
|
mystl::destroy(buffer, buffer + len); // 析构缓冲区中的元素
|
|
|
|
|
free(buffer); // 释放缓冲区
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
ptrdiff_t size() const noexcept { return len; } // 返回缓冲区实际大小
|
|
|
|
|
ptrdiff_t requested_size() const noexcept { return original_len; } // 返回申请的缓冲区大小
|
|
|
|
|
T* begin() noexcept { return buffer; } // 返回缓冲区开始指针
|
|
|
|
|
T* end() noexcept { return buffer + len; } // 返回缓冲区结束指针
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void allocate_buffer(); // 分配缓冲区
|
|
|
|
|
void initialize_buffer(const T&, std::true_type) {}
|
|
|
|
|
void initialize_buffer(const T& value, std::false_type)
|
|
|
|
|
{
|
|
|
|
|
mystl::uninitialized_fill_n(buffer, len, value);
|
|
|
|
|
} // 使用值初始化缓冲区
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
temporary_buffer(const temporary_buffer&); // 禁用拷贝构造函数
|
|
|
|
|
void operator=(const temporary_buffer&); // 禁用赋值运算符
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 构造函数
|
|
|
|
|
template <class ForwardIterator, class T>
|
|
|
|
|
temporary_buffer<ForwardIterator, T>::temporary_buffer(ForwardIterator first, ForwardIterator last)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
len = mystl::distance(first, last); // 计算迭代器之间的距离
|
|
|
|
|
allocate_buffer(); // 分配缓冲区
|
|
|
|
|
if (len > 0)
|
|
|
|
|
{
|
|
|
|
|
initialize_buffer(*first, std::is_trivially_default_constructible<T>()); // 初始化缓冲区
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (...)
|
|
|
|
|
{
|
|
|
|
|
free(buffer); // 异常时释放缓冲区
|
|
|
|
|
buffer = nullptr;
|
|
|
|
|
len = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~auto_ptr() { delete m_ptr; }
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 重载 operator* 和 operator->
|
|
|
|
|
T& operator*() const { return *m_ptr; }
|
|
|
|
|
T* operator->() const { return m_ptr; }
|
|
|
|
|
|
|
|
|
|
// 获得指针
|
|
|
|
|
T* get() const { return m_ptr; }
|
|
|
|
|
|
|
|
|
|
// 释放指针
|
|
|
|
|
T* release()
|
|
|
|
|
{
|
|
|
|
|
T* tmp = m_ptr;
|
|
|
|
|
m_ptr = nullptr;
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重置指针
|
|
|
|
|
void reset(T* p = nullptr)
|
|
|
|
|
{
|
|
|
|
|
if (m_ptr != p)
|
|
|
|
|
|
|
|
|
|
// allocate_buffer 函数
|
|
|
|
|
template <class ForwardIterator, class T>
|
|
|
|
|
void temporary_buffer<ForwardIterator, T>::allocate_buffer()
|
|
|
|
|
{
|
|
|
|
|
delete m_ptr;
|
|
|
|
|
m_ptr = p;
|
|
|
|
|
original_len = len;
|
|
|
|
|
if (len > static_cast<ptrdiff_t>(INT_MAX / sizeof(T)))
|
|
|
|
|
len = INT_MAX / sizeof(T); // 检查 len 是否超出 T 类型能表示的最大数量
|
|
|
|
|
while (len > 0)
|
|
|
|
|
{
|
|
|
|
|
buffer = static_cast<T*>(malloc(len * sizeof(T))); // 分配内存
|
|
|
|
|
if (buffer)
|
|
|
|
|
break; // 分配成功,退出循环
|
|
|
|
|
len /= 2; // 申请失败时减少申请空间大小
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
|
// 模板类: auto_ptr
|
|
|
|
|
// 一个具有严格对象所有权的小型智能指针
|
|
|
|
|
template <class T>
|
|
|
|
|
class auto_ptr
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
typedef T elem_type; // 元素类型
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
T* m_ptr; // 实际指针
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 构造、复制、析构函数
|
|
|
|
|
explicit auto_ptr(T* p = nullptr) :m_ptr(p) {} // 构造函数
|
|
|
|
|
auto_ptr(auto_ptr& rhs) :m_ptr(rhs.release()) {} // 复制构造函数,获取另一个 auto_ptr 的所有权
|
|
|
|
|
template <class U>
|
|
|
|
|
auto_ptr(auto_ptr<U>& rhs) : m_ptr(rhs.release()) {} // 模板复制构造函数
|
|
|
|
|
|
|
|
|
|
auto_ptr& operator=(auto_ptr& rhs) // 复制赋值运算符
|
|
|
|
|
{
|
|
|
|
|
if (this != &rhs)
|
|
|
|
|
{
|
|
|
|
|
delete m_ptr; // 删除当前指针
|
|
|
|
|
m_ptr = rhs.release(); // 获取另一个 auto_ptr 的所有权
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
template <class U>
|
|
|
|
|
auto_ptr& operator=(auto_ptr<U>& rhs) // 模板复制赋值运算符
|
|
|
|
|
{
|
|
|
|
|
if (this->get() != rhs.get())
|
|
|
|
|
{
|
|
|
|
|
delete m_ptr; // 删除当前指针
|
|
|
|
|
m_ptr = rhs.release(); // 获取另一个 auto_ptr 的所有权
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~auto_ptr() { delete m_ptr; } // 析构函数,删除指针指向的对象
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// 重载 operator* 和 operator->
|
|
|
|
|
T& operator*() const { return *m_ptr; } // 重载解引用操作
|
|
|
|
|
T* operator->() const { return m_ptr; } // 重载成员访问操作
|
|
|
|
|
|
|
|
|
|
// 获得指针
|
|
|
|
|
T* get() const { return m_ptr; } // 获取原始指针
|
|
|
|
|
|
|
|
|
|
// 释放指针
|
|
|
|
|
T* release()
|
|
|
|
|
{
|
|
|
|
|
T* tmp = m_ptr;
|
|
|
|
|
m_ptr = nullptr;
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 重置指针
|
|
|
|
|
void reset(T* p = nullptr)
|
|
|
|
|
{
|
|
|
|
|
if (m_ptr != p)
|
|
|
|
|
{
|
|
|
|
|
delete m_ptr; // 删除旧对象
|
|
|
|
|
m_ptr = p; // 重置指针
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace mystl
|
|
|
|
|
#endif // !MYTINYSTL_MEMORY_H_
|
|
|
|
|
|
|
|
|
|