-
Notifications
You must be signed in to change notification settings - Fork 0
/
cert-MEM56.cpp
81 lines (67 loc) · 1.62 KB
/
cert-MEM56.cpp
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
//
// MEM56-CPP. Do not store an already-owned pointer value in an unrelated smart pointer
//
#include <iostream>
#include <memory>
namespace {
void doubleFree()
{
int* i = ::new int(42); // diagnostic required
std::shared_ptr<int> p1(i);
std::shared_ptr<int> p2(i); // diagnostic required
}
struct B
{
virtual ~B() = default; // Polymorphic object
// ...
};
struct D : B
{
int i{};
void foo() { std::cout << "D::foo() called " << ++i << ". time" << std::endl; }
};
void bar(const std::shared_ptr<D>& derived) { derived->foo(); }
void danglingPtr()
{
std::shared_ptr<B> poly(new D); // diagnostic required
// ...
bar(std::shared_ptr<D>(dynamic_cast<D*>(poly.get()))); // diagnostic required
// Any use of poly will now result in accessing freed memory.
}
struct S
{
std::shared_ptr<S> g() { return std::shared_ptr<S>(this); } // diagnostic required
};
void realyBad()
{
std::shared_ptr<S> s1 = std::make_shared<S>();
// ...
std::shared_ptr<S> s2 = s1->g();
}
void better()
{
std::shared_ptr<B> poly = std::make_shared<D>();
// ...
bar(std::dynamic_pointer_cast<D, B>(poly));
// poly is still referring to a valid pointer value.
}
struct Super : std::enable_shared_from_this<Super>
{
std::shared_ptr<Super> g() { return shared_from_this(); }
};
void perfect()
{
std::shared_ptr<Super> s1 = std::make_shared<Super>();
std::shared_ptr<Super> s2 = s1->g();
}
} // namespace
int main()
{
for (int i = 0; i < 21; ++i) {
realyBad();
doubleFree();
danglingPtr();
better();
perfect();
}
}