Speicherzuordnung für eine Matrix in C

8

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")

    
Snogzvwtr 15.04.2010, 15:05
quelle

8 Antworten

2

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.

    
Andrew O'Reilly 15.04.2010, 16:33
quelle
6

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.

    
unwind 15.04.2010 15:08
quelle
2

Versuchen Sie, die Heap- und Stack-Limits in GCC zu erhöhen:

%Vor%     
Juliano 15.04.2010 15:13
quelle
1

Das sind beträchtliche Zuweisungen. Haben Sie versucht, sicherzustellen, dass malloc () erfolgreich ist?

Sie können malloc () für alle Ihre Arrays verwenden und sicherstellen, dass es jedes Mal erfolgreich ist.

    
WhirlWind 15.04.2010 15:08
quelle
1

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.

    
TheJuice 15.04.2010 16:07
quelle
1

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.

    
Martin 15.04.2010 16:16
quelle
0

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).

    
Prasoon Saurav 15.04.2010 15:12
quelle
0

Beide Matrizen passen nicht in die Grenzen Ihres Gedächtnisses. Sie können nur jeweils eine zuweisen.

Wenn Sie Y als 3000 statt als 6000 definieren, sollte Ihr Programm keinen segfault ausgeben.

    
mouviciel 15.04.2010 15:23
quelle

Tags und Links