Warum führt der folgende Code zu einem Segmentierungsfehler? (Ich versuche zwei Matrizen gleicher Größe zu erstellen, eine mit statischer und die andere mit dynamischer Zuweisung)
%Vor%Seltsamerweise, wenn ich eine der Matrix-Definitionen auskommentiere, läuft der Code gut. So:
%Vor%oder
%Vor%Ich führe GCC unter Linux auf einem 32-Bit-Rechner aus.
Bearbeiten: Überprüfen, ob malloc () erfolgreich ist:
%Vor%Nichts wird ausgedruckt, wenn ich es ausführe (erwarte natürlich "Segmentierungsfehler")
Sie erhalten einen Segmentierungsfehler, was bedeutet, dass Ihr Programm versucht, auf eine Speicheradresse zuzugreifen, die seinem Prozess nicht zugewiesen wurde. Das Array a
ist eine lokale Variable und somit Speicher aus dem Stack. Wenn unwind
darauf hinweist a
benötigt 120 MB Speicher. Dies ist fast sicher größer als der Stapelspeicher, den das Betriebssystem Ihrem Prozess zugewiesen hat. Sobald die for-Schleife über das Ende des Stapels hinausgeht, erhalten Sie einen Segmentierungsfehler.
In Linux wird die Stack-Größe vom Betriebssystem und nicht vom Compiler gesteuert. Versuchen Sie Folgendes: -
%Vor%In der Antwort sollte eine Zeile wie folgt angezeigt werden: -
%Vor%Dies bedeutet, dass jeder Prozess 10 MByte Speicherplatz erhält, was für Ihr großes Array nicht annähernd ausreicht.
Sie können die Stack-Größe mit einem ulimit -s <stack size>
-Befehl anpassen, aber ich vermute, dass Sie keine 120Mbyte Stack-Größe auswählen können!
Die einfachste Lösung besteht darin, a
anstelle einer lokalen Variablen zu einer globalen Variablen zu machen.
Ihre Variable a
erfordert auf einem 32-Bit-System 5000 * 6000 * 4 = 120 MB Stapelspeicher. Es ist möglich, dass dies einen Grenzwert verletzt, der den Segmentierungsfehler verursacht.
Es ist natürlich auch möglich, dass malloc()
an einem bestimmten Punkt fehlschlägt, was dazu führen könnte, dass Sie einen NULL
-Zeiger dereferenzieren.
Ein Stack-Überlauf (wie geeignet!) kann zu einem Segmentierungsfehler führen, den Sie hier zu sehen scheinen.
Im dritten Fall wird der Stapelzeiger an eine ungültige Adresse verschoben, wird aber für nichts mehr verwendet, da das Programm dann beendet wird. Wenn Sie eine Operation nach der Stapelzuordnung einfügen, sollten Sie einen segfault erhalten.
Vielleicht ändert der Compiler nur den Stapelzeiger auf einen großen Wert, verwendet ihn aber nie und verursacht daher niemals eine Speicherzugriffsverletzung.
Versuchen Sie, alle Elemente von A in Ihrem dritten Beispiel zu initialisieren? Ihr erstes Beispiel versucht, B nach A auf dem Stack zuzuordnen und auf den Stack zuzugreifen, der auf der ersten Zuweisung zu B hoch ist, was den Segfault verursacht.
Ihr 3. Code funktioniert auch nicht (zumindest auf meinem System).
Versuchen Sie stattdessen, dem Array a
auf dem Heap Speicher zuzuweisen (wenn Dimensionen groß sind).
Tags und Links c pointers memory-management