große lokale Variablen in Funktionen + globale Variablen = SEGMENTATION FAULT ?
-
Hi,
ist das normal, dass Segmentation Faults entstehen, wenn die lokalen Variablen einer Funktion zuviel Speicher einnehmen? In einem anderen Programm konnte ich sogar im Debugger beobachten, dass dadurch Konstanten (!!) verändert wurden.
Ich habe in letzter Zeit schon ein wenig in Assembler programmiert und weiss daher, dass lokale Variablen einer Funktion (unter Linux) auf dem Stack landen... Daher glaube ich, dass der Stack evtl. zu weit nach oben wächst und dann irgendwas überschreibt... aber sollte dem Compiler sowas nicht auffallen? Immerhin ist die lokale arr-Variable von fester Größe.
ich habe folgendes Testprogramm gebastelt, um das Problem zu veranschaulichen:
#include <iostream> #include <cassert> using namespace std; double c1 = 1; double c2 = 2; double c3 = 3; double c4 = 4; double c5 = 5; double c6 = 6; double c7 = 7; double c8 = 8; double c9 = 9; double c10 = 10; void test() { double arr[300][300][300]; // Segmenatation Fault ?!... aber nur wenn Variable arr zuviel Speicher belegt :D cout << c1 << ", " << c2 << ", " << c3 << ", " << c4 << ", " << c5 << ", " << c6 << ", " << c7 << ", " << c8 << ", " << c9 << ", " << c10 << endl; assert(c1 == 1); assert(c2 == 2); assert(c3 == 3); assert(c4 == 4); assert(c5 == 5); assert(c6 == 6); assert(c7 == 7); assert(c8 == 8); assert(c9 == 9); assert(c10 == 10); } int main(int argc, char* argv[]) { test(); }Ist der einzige Ausweg in diesem Fall wirklich nur ein dynamisches Array?
-
So ist es. Der Stack nimmt nicht beliebig viel auf, insbesondere keine 200MB, eher sowas im Kilobyte-Bereich. Für Größeres musst du den Heap benutzen.
-
moormaster schrieb:
double arr[300][300][300];
-
Ich weiss selbst, dass das groß is
Mich wundert es nur, dass der Compiler nix dazu sagt... der müsste doch als erster merken, dass das nich auf den Stack passt?Ich habe ein großes Programm, was mal jmd. geschrieben hat, welches derart große Arrays verwendet hat... Das lief auch so auf einem Cluster mit 64 Bit.
Bei Wechsel der plattform auf "Normalrechner" machen diese großen Arrays nun Probleme und ich muss offenbar zusehen, dass der ganze Kram nun dynamisch alloziiert wird

-
moormaster schrieb:
Ich habe ein großes Programm, was mal jmd. geschrieben hat, welches derart große Arrays verwendet hat...
Ich frag jetzt nicht, wie man auf solche Ideen kommt...
-
Auf diese Idee kommt man wohl, wenn man nur programmiert, um ein Problem zu lösen und sich nicht mit dynamischer Speicherreservierung herumplagen möchte... es war nicht meine Idee die Arrays so anzulegen
Ich habe nur versucht mich darumzudrücken, das alles auch noch ändern zu müssen 
-
Der Compiler sagt nix dazu weil er üblicherweise die grösse des Stacks nicht kennt. Die Stackgrösse kannst du oft beim Linken angeben. Beim MSVC z.B. (genauer Visual Studio) gibt's dazu ein hübsches Feld in den Linker-Einstellungen, da kannst du ja mal "524288000" (500MB) reinschreiben wenn du willst (falls du Visual Studio verwendest).
Wenn das Programm nur einen einzigen Thread verwendet sollte das sogar auf normalen 32 Bit Windows Systemen laufen.
-
Danke, ich werd mal die manpages vom g++ durchschauen, welcher Parameter dafür zuständig ist

-
Das hat nicht einmal was mit dem Programm an sich zu tun. Unter Linux zB einfach mit ulimit -s <LIMIT> die gewünschte Stackgröße setzen.
-
Fellhuhn schrieb:
Das hat nicht einmal was mit dem Programm an sich zu tun. Unter Linux zB einfach mit ulimit -s <LIMIT> die gewünschte Stackgröße setzen.
Danke! Das hat definitiv gepasst
Die alte Grenze des Stacks stand auf 8 MB, was in etwa zu meinen Beobachtungen passt. Stell ich das auf > ~205Mb dann läuft obiges Programm ohne Fehler durch.Können mir durch eine zu eine hohe Stack-Grenze irgendwelche Nachteile entstehen? Bleibt dann generell weniger Platz für dynamisch alloziierten Speicher oder erst, wenn der Stack tatsächlich so groß wird?
-
Abgesehen davon das es "schlechter Stil" ist, weil man normalerweise nicht von jedem erwarten kann das er manuell seinen Stack einstellt, ist der einzige Nachteil das der dynamische Speicherbereich der dem Prozess zur Verfügung gestellt wird entsprechend kleiner wird. Also im Grunde hast du die gleiche Menge an Speicher, nur eben weniger Heap, dafür mehr Stack.
-
Ok
