Frage zu verfügbarem Stack


  • Gesperrt

    Hallo

    Augrund der Fragen und Antworten im Thema Fehlender Standardkonstruktor (Bullet Physics) zu Stack und Heap habe ich folgendes versucht:

    Dabei ergab sich z.B. folgende Ausgabe (im "Debug-Modus x86" mit MSVC):


    Adresse index 15726884
    (vermutlich) Bytes bis zur naechsten Adresse -12
    Adresse size0 15726872
    (vermutlich) Bytes bis zur naechsten Adresse -12
    Adresse size1 15726860
    
    (vermutlich) Bytes bis zur Adresse von stackarray0[4] -12
    
    size0 5
    Adresse stackarray0[0] 15726832
    (vermutlich) Bytes bis zur naechsten Adresse bzw. von der letzten Adresse zur ersten 4
    Adresse stackarray0[1] 15726836
    (vermutlich) Bytes bis zur naechsten Adresse bzw. von der letzten Adresse zur ersten 4
    Adresse stackarray0[2] 15726840
    (vermutlich) Bytes bis zur naechsten Adresse bzw. von der letzten Adresse zur ersten 4
    Adresse stackarray0[3] 15726844
    (vermutlich) Bytes bis zur naechsten Adresse bzw. von der letzten Adresse zur ersten 4
    Adresse stackarray0[4] 15726848
    (vermutlich) Bytes bis zur naechsten Adresse bzw. von der letzten Adresse zur ersten -16
    
    (vermutlich) Bytes von Adresse stackarray0[0] bis stackarray1[25599] -12
    
    size1 25600
    Adresse stackarray1[25599] 15726820
    Adresse stackarray1[0] 15624424
    
    (vermutlich) Bytes von Adresse index bis heappointer0 3383388
    
    Adresse heappointer0 19110272
    (vermutlich) Bytes bis zur naechsten Adresse -14784
    Adresse heappointer1 19095488
    

    Naja, wie auch immer. Versuchte mich z.B. an die Fehlermeldung stackoverflow heranzutasten, wobei ein Wert - der zuvor keinen Fehler auslöste - auf einmal einen Fehler auslöste. Auch ändern sich die Adressen bei jedem neuen Start und die Abstände zwischen den Adressen unterschieden sich im Debug und im Release "Modus".

    Kurz geschrieben, möchte ich fragen, wie lässt sich die Grösse des verfügbaren Stack-Speicher herausfinden (Wobei nicht sehr viel Speicher zur Verfügung zu sein scheint, also 4 \cdot 256 \cdot 1000 Bytes hat schon Fehler ausgelöst und auch schon nicht).





  • Den Stack kannst du beim Betriebssystem abfragen.

    Windows: https://docs.microsoft.com/de-de/windows/desktop/api/processthreadsapi/nf-processthreadsapi-getcurrentthreadstacklimits
    Linux: http://man7.org/linux/man-pages/man2/getrusage.2.html)

    @titan99_ sagte in Frage zu verfügbarem Stack:

    Naja, wie auch immer. Versuchte mich z.B. an die Fehlermeldung stackoverflow heranzutasten, wobei ein Wert - der zuvor keinen Fehler auslöste - auf einmal einen Fehler auslöste. Auch ändern sich die Adressen bei jedem neuen Start und die Abstände zwischen den Adressen unterschieden sich im Debug und im Release "Modus".

    Adressen werden bei jedem Start zufällig gesetzt um das Ausnutzen von Sicherheitslücken zu erschweren: https://de.wikipedia.org/wiki/Address_Space_Layout_Randomization

    Release und Debug Modus nutzen in der Regel unterschiedliche Optimierungsstufen. Außerdem werden im Debug zusätzliche Checks ausgeführt. Da kann die Anordnung im Speicher durchaus unterschiedlich sein

    @titan99_ sagte in Frage zu verfügbarem Stack:

    Wobei nicht sehr viel Speicher zur Verfügung zu sein scheint, also 4 \cdot⋅ 256 \cdot⋅ 1000 Bytes hat schon Fehler ausgelöst und auch schon nicht

    Unter Windows ist 1 MB Stack der Standard. Die stehen aber nicht nur allein für deine Daten zu Verfügung. Wenn deine main Methode aufgerufen wird liegen z.B. bereits Daten auf dem Stack, und wenn du andere Methoden aufrufst werden Parameter zum Teil über den Stack übergeben etc.


  • Gesperrt

    Vielen Dank für die Antworten 🙂 . War mir bisher gar nicht so bewusst, dass so wenig Stack zur Verfügung steht. Nach den Links und den Antworten nehme ich an, dass unter Windows je Thread normalerweise 1 MB Stack zur Verfügung steht.

    So denke ich jetzt, dass es Sinn macht, wenn die Grösse einer Variablenadresse kleiner ist als die Variable (also bei x86 gehe ich von 4 Bytes / 32 Bit für die Grösse einer Variablenadresse aus), bei Funktionsparametern Variablen const Referenz zu verwenden anstatt einfach eine Kopie zu verwenden, wenn die Variable nicht verändert werden soll.

    Edit: Oder doch nicht immer?

    dynamicsworld->setGravity(btVector3(0.f, -9.81f, 0.f))

    Also wird hier eine temporäres Objekt btVector3 auf dem Stack angelegt und als "const Referenz" "entgegengenommen".

    virtual void setGravity(const btVector3& gravity)

    Also das temporäre Objekt im Stack muss ja dann in der Funktion bestehen bleiben, sonst würde die Referenz ungültig.

    Entschuldigung dafür, dass ich manchmal unsicher bin, ob ich die üblichen Wörter verwende 🙄 .



  • Kann es sein, dass in Zeiten, in denen wir RAM im zweistelligen GB-Bereich und Festplatten mit mehreren TB erwarten, das Gefühl und das Auge fürs Wesentliche etwas zu kurz kommt?
    10^6 Bytes entsprechen knapp 600 Normseiten mit jeweils 1800 Anschlägen. Um dieses „Buch” zu füllen, brauchts schon etwas mehr, als mal ein paar Variablen als Wert zu übergeben...
    Man sollte es natürlich im Hinterkopf behalten (speziell bei rekursiven Aufrufen oder wirklich großen Arrays auf dem Stack [beides sollte ohnehin vermieden werden]), (viel) mehr aber auch nicht.



  • @titan99_ sagte in Frage zu verfügbarem Stack:

    dynamicsworld->setGravity(btVector3(0.f, -9.81f, 0.f))

    Also wird hier eine temporäres Objekt btVector3 auf dem Stack angelegt und als "const Referenz" "entgegengenommen".

    Ja.

    @titan99_ sagte in Frage zu verfügbarem Stack:

    virtual void setGravity(const btVector3& gravity)

    Also das temporäre Objekt im Stack muss ja dann in der Funktion bestehen bleiben, sonst würde die Referenz ungültig.

    Ja, bleibt am Leben:

    A temporary bound to a reference parameter in a function call (§5.2.2 [expr.call]) persists until the completion of the full expression containing the call.