回答編集履歴

1

追記

2020/06/01 06:19

投稿

episteme
episteme

スコア16612

test CHANGED
@@ -29,3 +29,153 @@
29
29
  myclass b = a;
30
30
 
31
31
  としたとき、a.p と b.p は別領域となります(からa,bが廃棄されるとき二重解放になりません)
32
+
33
+
34
+
35
+ [追記] 領域のnew/delete の様子をプリントしてみました:
36
+
37
+ ```C++
38
+
39
+ #include <iostream>
40
+
41
+ #include <cstdlib>
42
+
43
+ using namespace std;
44
+
45
+
46
+
47
+ class myclass {
48
+
49
+ int* p;
50
+
51
+ public:
52
+
53
+ myclass(int i);
54
+
55
+ myclass(const myclass& ob);
56
+
57
+ ~myclass() { std::cout << "delete " << (void*)p << "\n"; delete p; }
58
+
59
+ friend int getval(myclass o);
60
+
61
+ };
62
+
63
+ myclass::myclass(int i)
64
+
65
+ {
66
+
67
+ p = new int;
68
+
69
+ std::cout << "new " << (void*)p << "\n";
70
+
71
+ if (!p) {
72
+
73
+ cout << "メモリ割り当てエラー\n";
74
+
75
+ exit(1);
76
+
77
+ }
78
+
79
+ *p = i;
80
+
81
+ }
82
+
83
+ myclass::myclass(const myclass& ob)
84
+
85
+ {
86
+
87
+ p = new(nothrow) int;
88
+
89
+ if (!p) {
90
+
91
+ cout << "メモリ割り当てエラー\n";
92
+
93
+ exit(1);
94
+
95
+ }
96
+
97
+ std::cout << "new " << (void*)p << "\n";
98
+
99
+ *p = *ob.p;
100
+
101
+ }
102
+
103
+ int getval(myclass o)
104
+
105
+ {
106
+
107
+ std::cout << "getval\n";
108
+
109
+ return *o.p; // 値を取得する
110
+
111
+ }
112
+
113
+ int main()
114
+
115
+ {
116
+
117
+ myclass a(1), b(2);
118
+
119
+ cout << getval(a) << " " << getval(b);
120
+
121
+ cout << "\n";
122
+
123
+ cout << getval(a) << " " << getval(b);
124
+
125
+ cout << "\n";
126
+
127
+ return 0;
128
+
129
+ }
130
+
131
+ ```
132
+
133
+ 実行結果:
134
+
135
+ ```
136
+
137
+ new 000002324AA76DE0
138
+
139
+ new 000002324AA76D40
140
+
141
+ new 000002324AA76E80
142
+
143
+ getval
144
+
145
+ delete 000002324AA76E80
146
+
147
+ 1 new 000002324AA76E10
148
+
149
+ getval
150
+
151
+ delete 000002324AA76E10
152
+
153
+ 2
154
+
155
+ new 000002324AA76DD0
156
+
157
+ getval
158
+
159
+ delete 000002324AA76DD0
160
+
161
+ 1 new 000002324AA76CF0
162
+
163
+ getval
164
+
165
+ delete 000002324AA76CF0
166
+
167
+ 2
168
+
169
+ delete 000002324AA76D40
170
+
171
+ delete 000002324AA76DE0
172
+
173
+ ```
174
+
175
+
176
+
177
+ getvalの前後でnew/deleteされてて、そのポインタ値は組になってます。
178
+
179
+ つまり、getvalの直前でコピーを作り、直後でそのコピーを廃棄しています。
180
+
181
+ なので二重解放になりません。