こんにちハロ
今回はCEDEC2015で話題になったCoverityクイズについての記事です.
今更な内容ですが,見たときに直ぐに解けなかったので備忘録として残しておきます.
参考文献
この記事の元ネタです.
別の調べ物をしていた時に発見しました.
ota42y.com
同じ内容のプログラムです.
tanku.hatenablog.jp
問題
問題のバグが潜んでいるソースコードに検証を追加したもの.
実行結果
0: 0, 0, 0 1: 0, 0, 0 2: 0, 0, 0 3: 0, 0, 0 4: 0, 0, 0 5: 0, 0, 0 6: 0, 0, 0 7: 0, 0, 0 8: 0, 0, 0 9: 0, 0, 0 0: 0, 0, 1 1: 1, 2, 2 2: 3, 3, 4 3: 4, 5, 5 4: 6, 6, 7 5: 7, 8, 8 6: 9, 9, 0 7: 0, 0, 0 8: 0, 0, 0 9: 0, 0, 0
問題点
添え字と同じ数値をメンバ変数x,y,zに代入したいのに,暗黙の型変換(アップ・キャスト)によってアドレス位置がずれてしまった.
本来はこうなってほしい↓.
0: 0, 0, 0 1: 1, 1, 0 2: 2, 2, 0 ...
図解
解決策
横着せずに1つずつ処理する(参考文献とほぼ同じ).
根本的に解決したい場合は,参考文献を参照してください.
メモリ構造
Coverityクイズだけでは薄いので,クラスのメモリ構造について簡単な検証をして見ました.
特に解説はないですが,クラス配置ついてなんとなく理解が深まった気がします.
sizeof int : 4 base : 8 derived : 12 base_h_f : 8 derived_h_f: 12 base_class address base : 0x7ffcc71ede30 base.x: 0x7ffcc71ede30 base.y: 0x7ffcc71ede34 derived_class address derived : 0x7ffcc71ede20 derived.x: 0x7ffcc71ede20 derived.y: 0x7ffcc71ede24 derived.z: 0x7ffcc71ede28 base_have_func address base_h_f : 0x7ffcc71ede10 base_h_f.x : 0x7ffcc71ede10 base_h_f.y : 0x7ffcc71ede14 base_h_f::func : 0x4008a2 derived_have_func address derived_h_f : 0x7ffcc71ede00 derived_h_f.x : 0x7ffcc71ede00 derived_h_f.y : 0x7ffcc71ede04 derived_h_f.z : 0x7ffcc71ede08 derived_h_f::func : 0x4008a2 derived_h_f::funcX : 0x4008d2
まとめ
C++は奥が深い.