Die folgende statische Zuweisung ergibt einen Segmentierungsfehler
%Vor%Aber die folgende dynamische Zuweisung geht gut
%Vor%Die ulimit ist in Linux unbegrenzt festgelegt.
Kann mir jemand einen Hinweis geben, was passiert?
Wenn Sie sagen, dass ulimit auf unbegrenzt gesetzt ist, verwenden Sie die Option -s
? Andernfalls ändert sich das Stacklimit nicht, nur die Dateigröße ist begrenzt.
Es scheint jedoch trotzdem Stapellimits zu geben. Ich kann zuweisen:
%Vor%Und das Ausführen der Binärdatei bekomme ich:
%Vor%Jedoch, wenn ich auf dem Stapel zuteile, ist es:
%Vor%Was eindeutig nicht korrekt ist (was auf einen Überlauf hindeutet). Mit den ursprünglichen Zuordnungen ergeben die beiden die gleichen Ergebnisse:
%Vor% Beim Ausführen der Stack-Version kann ich jedoch keinen segfault erzeugen, unabhängig von der Größe des Arrays - auch wenn es mehr ist als der Gesamtspeicher auf dem System, wenn -s unlimited
gesetzt ist.
BEARBEITEN:
Ich habe einen Test mit malloc
in einer Schleife gemacht, bis es fehlgeschlagen ist:
Die Stack-Nutzung erreicht jedoch nie mehr als 4 GB.
Angenommen, Ihre Maschine hat tatsächlich genug freien Speicher, um 3,125 GiB Daten zuzuordnen, liegt der Unterschied wahrscheinlich in der Tatsache, dass die statische Zuweisung all diesen Speicher benötigt, um zusammenhängend zu sein (es ist eigentlich ein 3-dimensionales Array) Die dynamische Zuweisung benötigt nur zusammenhängende Blöcke von ungefähr 2048 * 8 = 16 KiB (es ist ein Array von Zeigern auf Arrays von Zeigern auf ziemlich kleine tatsächliche Arrays).
Es ist auch möglich, dass Ihr Betriebssystem Auslagerungsdateien für Heap-Speicher verwendet, wenn es ausläuft, aber nicht für den Stack-Speicher.
Es gibt eine sehr gute Diskussion über das Linux-Speichermanagement - und speziell den Stack - hier: 9.7 Stack overflow , es lohnt sich das Lesen.
Sie können diesen Befehl verwenden, um herauszufinden, was Ihr aktueller Stapel soft limit
ist
Unter Mac OS X ist das Hardlimit 64 MB, siehe Wie ändere ich die Stapelgröße mit ulimit oder pro Prozess unter Mac OS X für ein C- oder Ruby-Programm?
Sie können das Stack-Limit zur Laufzeit in Ihrem Programm ändern, siehe Ändere während der Kompilierung mit dem GNU-Compiler die Stapelgröße für eine C ++ - Anwendung in Linux
Ich habe Ihren Code mit der Probe dort kombiniert, hier ist ein Arbeitsprogramm
%Vor%Sie treffen ein Limit des Stapels. In Windows ist der Stack standardmäßig 1 MB groß, kann jedoch bei ausreichendem Speicherbedarf noch erweitert werden.
Auf vielen * nix-Systemen ist die Standard-Stack-Größe 512K.
Sie versuchen, 2048 * 2048 * 100 * 8 Bytes zuzuordnen, was über 2 ^ 25 (über 2G für Stapel) ist. Wenn Sie viel virtuellen Arbeitsspeicher zur Verfügung haben und dies immer noch auf dem Stack zuweisen möchten, verwenden Sie ein anderes Stack-Limit, während Sie die Anwendung verknüpfen.
Linux: Wie wird die Größe des ausführbaren GCC-Stacks erhöht? Ändern Sie die Stapelgröße für ein C ++ Anwendung in Linux während der Kompilierung mit GNU-Compiler
Windows: Ссылка
Tags und Links c linux memory-management