-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Expand file tree
/
Copy pathallocators.cpp
More file actions
139 lines (113 loc) · 3.91 KB
/
allocators.cpp
File metadata and controls
139 lines (113 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// semmle-extractor-options: -std=c++17
typedef unsigned long size_t;
namespace std {
enum class align_val_t : size_t {};
}
void* operator new(size_t, float);
void* operator new[](size_t, float);
void* operator new(size_t, std::align_val_t, float);
void* operator new[](size_t, std::align_val_t, float);
void operator delete(void*, float);
void operator delete[](void*, float);
void operator delete(void*, std::align_val_t, float);
void operator delete[](void*, std::align_val_t, float);
struct String {
String();
String(const String&);
String(String&&);
String(const char*);
~String();
String& operator=(const String&);
String& operator=(String&&);
const char* c_str() const;
private:
const char* p;
};
struct SizedDealloc {
char a[32];
void* operator new(size_t);
void* operator new[](size_t);
void operator delete(void*, size_t);
void operator delete[](void*, size_t);
};
struct alignas(128) Overaligned {
char a[256];
};
struct PolymorphicBase {
virtual ~PolymorphicBase();
};
void OperatorNew() {
new int; // No constructor
new(1.0f) int; // Placement new, no constructor
new int(); // Zero-init
new String(); // Constructor
new(1.0f) String("hello"); // Placement new, constructor with args
new Overaligned; // Aligned new
new(1.0f) Overaligned(); // Placement aligned new
}
void OperatorDelete() {
delete static_cast<int*>(nullptr); // No destructor
delete static_cast<String*>(nullptr); // Non-virtual destructor, with size.
delete static_cast<SizedDealloc*>(nullptr); // No destructor, with size.
delete static_cast<Overaligned*>(nullptr); // No destructor, with size and alignment.
delete static_cast<PolymorphicBase*>(nullptr); // Virtual destructor
delete static_cast<const String*>(nullptr); // Pointer to const
}
void OperatorNewArray(int n) {
new int[n]; // No constructor
new(1.0f) int[n]; // Placement new, no constructor
new String[n]; // Constructor
new Overaligned[n]; // Aligned new
new String[10]; // Constant size
}
int* const GetPointer();
void OperatorDeleteArray() {
delete[] static_cast<int*>(nullptr); // No destructor
delete[] static_cast<String*>(nullptr); // Non-virtual destructor, with size.
delete[] static_cast<SizedDealloc*>(nullptr); // No destructor, with size.
delete[] static_cast<Overaligned*>(nullptr); // No destructor, with size and alignment.
delete[] static_cast<PolymorphicBase*>(nullptr); // Virtual destructor
delete[] GetPointer();
}
struct FailedInit {
FailedInit();
~FailedInit();
void* operator new(size_t); // Non-placement
void* operator new[](size_t); // Non-placement
void operator delete(void*, size_t); // Sized deallocation
void operator delete[](void*, size_t); // Sized deallocation
};
struct alignas(128) FailedInitOveraligned {
FailedInitOveraligned();
~FailedInitOveraligned();
void* operator new(size_t, std::align_val_t, float); // Aligned placement
void* operator new[](size_t, std::align_val_t, float); // Aligned placement
void operator delete(void*, std::align_val_t, float); // Aligned placement
void operator delete[](void*, std::align_val_t, float); // Aligned placement
};
void TestFailedInit(int n) {
new FailedInit();
new FailedInit[n];
new(1.0f) FailedInitOveraligned();
new(1.0f) FailedInitOveraligned[10];
}
// --- non-allocating placement new ---
namespace std {
typedef unsigned long size_t;
struct nothrow_t {};
extern const nothrow_t nothrow;
}
void* operator new (std::size_t size, void* ptr) noexcept;
void* operator new[](std::size_t size, void* ptr) noexcept;
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
int overloadedNew() {
char buf[sizeof(int)];
new(&buf[0]) int(5);
int five = *(int*)buf;
new(buf) int[1];
*(int*)buf = 4;
new(std::nothrow) int(3); // memory leak
new(std::nothrow) int[2]; // memory leak
return five;
}