Makin さんが書きました:消去のコードのところで、一度schoolの配列の一つを消去して、また新しく同じクラスを作っていますが、
一つではなく、見つかった要素以降全てを消去していますね。
Makin さんが書きました:コード:
//消去したい生徒のIDが見つかった場合
if (flag == 1) {
for (i; i < numStudent - 1; i++) {
delete school[i];
school[i] = new Student;
school[i] = school[i + 1];
}
numStudent--;
delete school[i];
}
このコードが何をしているかを、i = 2, numStudent = 5の場合の例で図示します。
1. 初期状態
(ループ1周目:i = 2)
2. delete school
;
3. school = new Student;
4. school = school[i + 1];
(ループ2周目:i = 3)
5. delete school;
6. school = new Student;
7. school = school[i + 1];
(ループの後)
8. delete school;

- 提示されたコードの動作
- kurasunohairetunoitibunomiwosyoukyositainodesuga-20170423.png (36.37 KiB) 閲覧数: 2362 回
このように、この消去操作を行うと、deleteで削除されたオブジェクトへのポインタが配列の有効とみなされる部分に格納されることになります。
deleteで削除されたオブジェクトにアクセス(ポインタをデリファレンスして読みor書き)してしまうと、そこに確保された他のオブジェクトのデータの破壊などが発生することがあり、危険です。
これをdangling pointerといいます。
また、新たに確保されたオブジェクトのポインタが格納された変数をすぐに他のポインタで上書きしてしまい、メモリリークも発生しています。
例えば、こうするといいでしょう。
コード:
//消去したい生徒のIDが見つかった場合
if (flag == 1) {
delete school[i]; // その生徒を消去する
for (i; i < numStudent - 1; i++) { // 残りの生徒のデータを前にずらす
school[i] = school[i + 1];
}
numStudent--;
}
[quote="Makin" id=3,19085,144754]消去のコードのところで、一度schoolの配列の一つを消去して、また新しく同じクラスを作っていますが、[/quote]
一つではなく、見つかった要素以降全てを消去していますね。
[quote="Makin" id=3,19085,144754][code]
//消去したい生徒のIDが見つかった場合
if (flag == 1) {
for (i; i < numStudent - 1; i++) {
delete school[i];
school[i] = new Student;
school[i] = school[i + 1];
}
numStudent--;
delete school[i];
}
[/code][/quote]
このコードが何をしているかを、i = 2, numStudent = 5の場合の例で図示します。
1. 初期状態
(ループ1周目:i = 2)
2. delete school[i];
3. school[i] = new Student;
4. school[i] = school[i + 1];
(ループ2周目:i = 3)
5. delete school[i];
6. school[i] = new Student;
7. school[i] = school[i + 1];
(ループの後)
8. delete school[i];
[attachment=0]kurasunohairetunoitibunomiwosyoukyositainodesuga-20170423.png[/attachment]
このように、この消去操作を行うと、deleteで削除されたオブジェクトへのポインタが配列の有効とみなされる部分に格納されることになります。
deleteで削除されたオブジェクトにアクセス(ポインタをデリファレンスして読みor書き)してしまうと、そこに確保された他のオブジェクトのデータの破壊などが発生することがあり、危険です。
これをdangling pointerといいます。
また、新たに確保されたオブジェクトのポインタが格納された変数をすぐに他のポインタで上書きしてしまい、メモリリークも発生しています。
例えば、こうするといいでしょう。
[code]
//消去したい生徒のIDが見つかった場合
if (flag == 1) {
delete school[i]; // その生徒を消去する
for (i; i < numStudent - 1; i++) { // 残りの生徒のデータを前にずらす
school[i] = school[i + 1];
}
numStudent--;
}
[/code]