-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathA15-0-2.cpp
More file actions
149 lines (101 loc) · 2.12 KB
/
A15-0-2.cpp
File metadata and controls
149 lines (101 loc) · 2.12 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
140
141
142
143
144
145
146
147
148
149
// Rule: A15-0-2
// Source line: 22060
// Original file: A15-0-2.cpp
//% $Id: A15-0-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $
#include <cstdint>
#include <cstring>
class C1
{
public:
C1(const C1& rhs)
{
CopyBad(rhs);
// Non-compliant - if an exception is thrown, an object
// will be left in an indeterminate state
CopyGood(rhs); // Compliant - full object will be properly copied or
// none of its properties will be changed
}
~C1() {
delete[] e;
}
void CopyBad(const C1& rhs)
{
if (this != &rhs)
{
delete[] e;
e = nullptr; // e changed before the block where an exception can
// be thrown
s = rhs.s; // s changed before the block where an exception can be
// thrown
if (s > 0)
{
e = new std::int32_t[s];
// If an exception will be thrown
// here, the
// object will be left in an indeterminate
// state
std::memcpy(e, rhs.e, s * sizeof(std::int32_t));
}
}
}
void CopyGood(const C1& rhs)
{
std::int32_t* eTmp = nullptr;
if (rhs.s > 0)
{
eTmp = new std::int32_t[rhs.s];
// If an exception will be thrown
// here, the
// object will be left unchanged
std::memcpy(eTmp, rhs.e, rhs.s * sizeof(std::int32_t));
}
delete[] e;
e = eTmp;
s = rhs.s;
}
private:
std::int32_t* e;
std::size_t s;
};
class A
{
public:
A() = default;
};
class C2
{
public:
C2() : a1(new A), a2(new A)
// Non-compliant - if a2 memory allocation
// fails, a1 will never be deallocated
{}
private:
A* a1;
A* a2;
};
class C3
{
public:
C3() : a1(nullptr), a2(nullptr)
{
// Compliant
try
{
a1 = new A;
a2 = new A;
// If memory allocation for a2 fails, catch-block will
// deallocate a1
}
catch (...)
{
delete a1;
a1 = nullptr;
delete a2;
a2 = nullptr;
throw;
}
}
private:
A* a1;
A* a2;
};