MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
trace_memory.hpp
1#ifndef MSTL_CORE_MEMORY_TRACE_MEMORY_HPP__
2#define MSTL_CORE_MEMORY_TRACE_MEMORY_HPP__
3#ifdef MTL_STATE_DEBUG__
4#include "../container/unordered_map.hpp"
5#include "../system/console.hpp"
6#include "../system/stacktrace.hpp"
7#else
9#endif
11
12template <typename T>
13class trace_allocator;
14
15#ifdef MTL_STATE_DEBUG__
16
17template <typename T>
18class trace_allocator {
19 static_assert(is_allocable_v<T>, "allocator can`t alloc void, reference, function or const type.");
20
21public:
22 using value_type = T;
23 using pointer = T*;
24 using const_pointer = const T*;
25 using reference = T&;
26 using const_reference = const T&;
27 using size_type = size_t;
28 using difference_type = ptrdiff_t;
29
30 template <typename U>
31 struct rebind {
32 using other = trace_allocator<U>;
33 };
34
35 trace_allocator() = default;
36
37 template <typename U>
38 trace_allocator(const trace_allocator<U>& a) : traces_(a.traces_) {}
39 trace_allocator& operator =(const trace_allocator& a) {
40 if (_MSTL addressof(a) == this) return *this;
41 traces_ = a.traces_;
42 return *this;
43 }
44
45 ~trace_allocator() {
46 if (!traces_.empty()) {
47 _MSTL printcln(color::red(), "Memory leaks detected! \n");
48 print_stacktrace();
49 }
50 }
51
52 void print_stacktrace() const {
53 for(auto& entry : traces_) {
54 if (entry.first == 0) continue;
55 _MSTL printcln(color::red(), "Leaked pointer: ", static_cast<void*>(entry.first));
56 _MSTL printcln(color::red(), "Allocation stack trace:\n", entry.second);
57 }
58 }
59
60 MSTL_NODISCARD MSTL_ALLOC_OPTIMIZE pointer allocate(const size_type n) {
61 pointer ptr = _MSTL allocator<T>().allocate(n);
62 stacktrace st{};
63 traces_[ptr] = _MSTL move(st);
64 return ptr;
65 }
66
67 MSTL_NODISCARD MSTL_ALLOC_OPTIMIZE pointer allocate() {
68 return this->allocate(1);
69 }
70
71 void deallocate(pointer p, const size_type n) noexcept {
72 auto it = traces_.find(p);
73 if (it != traces_.end()) {
74 traces_.erase(it);
75 }
76 _MSTL allocator<T>().deallocate(p, n);
77 }
78
79 void deallocate(pointer p) noexcept {
80 this->deallocate(p, 1);
81 }
82
83private:
84 _MSTL unordered_map<T*, _MSTL stacktrace> traces_;
85};
86
87template <typename T, typename U>
88bool operator ==(const trace_allocator<T>&, const trace_allocator<U>&) noexcept {
89 return true;
90}
91
92template <typename T, typename U>
93bool operator !=(const trace_allocator<T>&, const trace_allocator<U>&) noexcept {
94 return false;
95}
96
97#else
98
99template <typename T>
100class trace_allocator : public standard_allocator<T> {};
101
102#endif
103
105#endif // MSTL_CORE_MEMORY_TRACE_MEMORY_HPP__
MSTL_ALLOC_NODISCARD MSTL_CONSTEXPR20 static MSTL_ALLOC_OPTIMIZE pointer allocate()
分配单个元素内存
_INNER alloc_size_t size_type
大小类型
static MSTL_CONSTEXPR20 void deallocate(pointer p, const size_type n) noexcept
释放先前分配的内存
MSTL_CONSTEXPR20 standard_allocator & operator=(const standard_allocator &) noexcept=default
赋值运算符
MSTL_NODISCARD constexpr T * addressof(T &x) noexcept
获取对象的地址
bool operator!=(const function< Res(Args...)> &f, nullptr_t null) noexcept
不等于空指针比较
bool operator==(const function< Res(Args...)> &f, nullptr_t null) noexcept
等于空指针比较
standard_allocator< T > allocator
标准分配器别名
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
uint64_t size_t
无符号大小类型
int64_t ptrdiff_t
指针差类型
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
MSTL标准分配器