Guten Abend, ich hätte eine Frage bezüglich Heap und Stack; ich verwender malloc für einen FIFO Buffer. Wird der FIFO langsamer geleert als gefüllt wächst der Heap vom unteren Adressbereich natürlich immer weiter an in Richtung Stack, bis schließlich malloc 0 zurück gibt. Woher weiß aber malloc wann Schluss ist? Die Größe des Stacks kann malloc nicht kennen und es darf auch nicht bis zum oberen Ende gehen, weil irgendwo definitiv der Stack beginnt. Ich gehe daher davon aus, dass irgendwo definiert sein muss wie weit der Heap wachsen darf. Ist das richtig, und wenn ja wo, und vor allem wie kann ich den Wert ggf anpassen? Und was passiert eigentlich wenn der Heap den Stack küsst aber noch mehr auf den Stack muss? Überschreibt der Stack einfach gnadenlos meinen Heap oder weiß der Stack dass darunter Speicher vergeben ist und wenn letzteres was passiert dann? Sorry für die vielen Fragen, aber das interessiert mich gerade wirklich brennend! Gruß Stefan
http://www.rn-wissen.de/index.php/Speicherverbrauch_bestimmen_mit_avr-gcc#Nutzung_des_SRAM_durch_avr-gcc > Heap und Stack müssen sich den Speicher, der nicht von .data, .bss und .noinit belegt ist, teilen > Wird der Stackbereich zu groß, weil dort zu viele Daten abgelegt werden [...] dann überschreibt man damit womöglich andere Daten und es kommt zur Fehlfunktion des Programmes. Gleiches gilt, wenn die Obergrenze des Heap über der Untergrenze des Stabels hinauswächst. Das sollte eigentlich alles erklären. Weder der Heap noch der Stack wissen voneinander :) . Lies auch mal bei "Dynamischer RAM-Verbrauch" weiter. Vielleicht ist das __builtin_alloca was für dich?
Wass pasiert ist abhängig von der Hardware. Es ist zB nicht überall so, daß Stack auf den Heap folgt oder überhaupt ein linearer Speicher vorhanden ist. Ein Mechanismus ist, daß malloc _sbrk aufruft, um vom OS neuen Speicher anzufordern. Je nach implementierung überprüft sbrk gegen das vom Linker definierte Symbol _end/end. Hier eine Implementierung in der libnosys http://sourceware.org/cgi-bin/cvsweb.cgi/src/libgloss/libnosys/sbrk.c?rev=1.4&content-type=text/x-cvsweb-markup&cvsroot=src und für SPU http://sourceware.org/cgi-bin/cvsweb.cgi/src/libgloss/spu/sbrk.c?rev=1.4&content-type=text/x-cvsweb-markup&cvsroot=src auf Systemen mit OS wird dann ein Syscall ausgeführt, und das OS kümmert sich darum. Idr ist es einer Task nicht erlauft, neuen Speicher zu nehmen, aber diese kann ihn vom OS -- das dann mit erweiterten Rechten läuft -- anfordern.
Hallo Markus, schönen Dank für das Dokument, sehr interessant! Ich habe mir nun einfach damit geholfen das Symbol heap_end zu überschreiben: LDFLAGS += -Wl,--defsym=__heap_end=0x800900 Lieber wäre mir gewesen irgendwie das Symbol __malloc_margin hochzusetzten (ist stadardmäßig auf 32 gesetzt), aber das hat leider nicht geklappt. Nun begrenze ich die Heapgröße einfach so dass mehr Platz für den Stack ist. Gruß Stefan
Stefan schrieb: > Lieber wäre mir gewesen irgendwie das Symbol __malloc_margin > hochzusetzten (ist stadardmäßig auf 32 gesetzt), aber das hat leider > nicht geklappt. Muss gehen. __malloc_margin ist aber eine Variable, die muss man zur Laufzeit zuweisen. Im Gegensatz zu den expliziten Heapgrenzen kann man __malloc_margin auch beliebig während der Laufzeit verändern.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.