Matrix22
配列とデフォルトのコンストラクターを持つC++クラスがあります。
class Matrix22{
/* something more */
double mat[2][2];
Matrix22(){
for(int i=0; i<2; i++)
for(int j=0; j<2; j++)
mat[i][j] = i==j ? 1.0 : 0.0;
}
};
プログラムで使用しましたが、セグメンテーション違反が発生しました。残りは非常に難しく複雑だったので、私は単純なテストルーチンを作成しましたMatrix22()
。セグメンテーション違反はもうありません。
次にgdb
、問題をデバッグするために実行しました。別のテストルーチンからコンストラクターを呼び出すとgcc
、メンバー用にメモリが予約されmat
ます。スタックをナビゲートして、配列の数バイト後のリターンアドレスを確認できます。
メインプログラムでは、コンパイラは十分なスペースを予約していません。最初の要素(mat[0][0]
)が書き込まれますが、それ以降の書き込みは次のスタックフレームを上書きするだけです。また、コンストラクターの前と同様に、コマンドbt
が正しいバックトレースを返すことを確認できます。重要な割り当ての後、バックトレースが破損しています。
だから私の質問は:なぜある場合にはコンパイラ(またはリンカ?)が配列のために十分なスペースを予約しないのに、他の場合にはそれが起こらないのですか?
PS:両方の「テストケース」は同じコンパイラとフラグでコンパイルされ、同じオブジェクトファイルに対してもリンクされています。
編集:
セグメンテーション違反なしで機能する「単純な」テストケースは次のとおりです。
void test_Matrix22()
{
Framework::Math::Matrix22 matrix;
}
セグメンテーション違反を作成するコードは、クラスModuleShaddower
(混合ヘッダーと実装)にあります。
class ModuleShaddower{
public:
ModuleShaddower(PVModule& module, const EnvironmentalSetup& setup, const Position& position);
private:
Matrix22 rotMatrix90;
};
ModuleShaddower::ModuleShaddower(PVModule& module, const EnvironmentalSetup& setup, const Position& position)
: module (module), position(position), setup(setup), logger(LoggerFactory::getLoggerInstance())
{
double mat[][2] = {{0, -1},{1, 0}}; // This line will never be reached
rotMatrix90 = Matrix22(mat);
}
ご覧のとおり、それは残りの部分からかなりのものです。問題のあるコードを抽出しようとするかもしれませんが、これはあまり役に立たないと思います。