Ich habe eine C++ Klasse Matrix22
mit einem Array und einem Standard-Konstruktor:Warum reserviert der Compiler nicht genügend Speicherplatz auf dem Stack?
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;
}
};
Ich habe es in meinem Programm und einen Segmentation Fault bekam. Da der Rest ziemlich schwierig und kompliziert war, schrieb ich eine einfache Testroutine, die einfach Matrix22()
aufruft. Kein Seg-Fehler mehr.
Ich lief dann gdb
, um das Problem zu debuggen. Wenn ich den Konstruktor aus der separaten Testroutine aufrufe, reserviert gcc
Speicherplatz für das Element mat
. Ich kann durch den Stapel navigieren und die Rücksprungadresse einige Bytes nach dem Array sehen.
Im Hauptprogramm reserviert der Compiler nicht genügend Speicherplatz. Das erste Element (mat[0][0]
) wird geschrieben, aber jedes weitere Schreiben überschreibt einfach den nächsten Stapelrahmen. Ich kann auch überprüfen, dass wie vor dem Konstruktor der Befehl bt
ein korrektes Backtrace zurückgibt, wobei nach der kritischen Zuweisung das Backtrace beschädigt ist.
Also meine Frage ist: Warum reserviert in einem Fall der Compiler (oder der Linker?) Nicht genug Platz für das Array, während im anderen Fall das nicht passiert?
PS: Beide "Testfälle" sind mit dem gleichen Compiler und Flags kompiliert und auch gegen die gleichen Objektdateien gekoppelt.
edit:
Hier ist der "einfache" Testfall, der ohne seg Fehler funktioniert:
void test_Matrix22()
{
Framework::Math::Matrix22 matrix;
}
Der Code mit einem seg Fehler erzeugt in der Klasse ModuleShaddower
(vermischte Header und Implementierung):
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);
}
Wie Sie sehen, es ist ganz aus dem Rest. Ich werde vielleicht versuchen, den problematischen Code zu extrahieren, aber ich denke, das wird nicht viel helfen.
Können Sie den vollständigen Testfall bereitstellen? (die eine, die fehlschlägt) –
Was Oli sagte: Zeigen Sie uns, wie Sie die Klasse verwenden. –
Der kurze Test ist kein Problem. Die lange Version hat mehrere tausend Zeilen Code. Ich werde versuchen, einen Teil davon zu geben –