grosse array erzeugen



  • tobidope schrieb:

    Bashar schrieb:

    tobidope: Doch, unter Windows ist der Stack oftmals von begrenzer und relativ kleiner Größe. Wie kommst du eigentlich darauf, dass du den nur mit Rekursion sprengen kannst? Ich seh überhaupt nicht die Logik dahinter ...

    Hast du schon mal überlegt, was bei einem Funktionsaufruf passiert? Es müssen die Rücksprungadresse und alle lokalen Variablen gespeichert werden. Wo wohl?

    Bei einem Quicksort (bei mir waren es zum Schluss über 40.000 Aufrufe) kann man den Stack dann sprengen,

    Wenn die Rekursionstiefe nicht zur Programmierzeit bereits bekannt ist, sollte man auf Rekursion verzichten. Insbesondere in Anwendungsfällen wo es zu einer sehr tiefen Rekursion kommen kann. Eine rekursive Sortierfunktion auf eine sehr grosse Datenmenge anzuwenden ist nicht sinnvoll. Ein paar Character mehr, ein paar Rekursionsstufen mehr und es kann dir passieren dass dir der Stack nicht mehr ausreicht.

    Klassisches Beispiel:
    Treiber für eine Netzwerkkarte (Gigabit Ethernet).
    Netzwerkpakete sind ja nicht sonderlich gross, also alles schön auf dem Stack platziert. Den Buffer packen wir natürlich ebenso auf den Stack -- es hat ja massig Platz.
    Auf einer IA32 Hardware (wer es nicht weiss: Intel/AMD x86) für Windows und Linux war alles im Grünen Bereich. Aber auf einer RS/6000 bzw. Power4 Maschine mit IBM AIX ist der ganze Server immer mal wieder abgenippelt. Debugging des NIC Treibers hat gezeigt, dass das ganze an einem Stack-Overflow gekrankt hat. Nachdem der Stack durch Benutzung des Heap entlastet wurde lief der Treiber auch auf dieser Hard-/Softwarkombination stabil.

    Wer also portable Programme schreiben möchte oder muss, tut gut daran bereits zur Programmierzeit sich Gedanken zu machen was er wo (Stack oder Heap) ablegt.

    tobidope schrieb:

    aber wenn ich die Größe eines Array zuvor weiß, dann ist es viel sinnvoller diesen im Stack abzulegen.

    ...wenn es sich hierbei um eine überschaubare Datenmenge handelt dann ja.

    Es hat ja keiner was dagegen, einen char[255] oder char[2048] auf den Stack zu werfen. Aber ansonsten wäre eine Datenhaltung auf dem Heap per malloc()/free() angebracht.

    Arrays für Datenmengen die ich *nicht* vorher weiss sollten immer dynamisch (und somit auf dem Heap) angefordert werden.



  • Descartes schrieb:

    tobidope schrieb:

    Bashar schrieb:

    tobidope: Doch, unter Windows ist der Stack oftmals von begrenzer und relativ kleiner Größe. Wie kommst du eigentlich darauf, dass du den nur mit Rekursion sprengen kannst? Ich seh überhaupt nicht die Logik dahinter ...

    Hast du schon mal überlegt, was bei einem Funktionsaufruf passiert? Es müssen die Rücksprungadresse und alle lokalen Variablen gespeichert werden. Wo wohl?

    Bei einem Quicksort (bei mir waren es zum Schluss über 40.000 Aufrufe) kann man den Stack dann sprengen, aber wenn ich die Größe eines Array zuvor weiß, dann ist es viel sinnvoller diesen im Stack abzulegen. Es ist eine automatische Variable, die nur dann Platz verbraucht, wenn sie gerade genutzt wird.

    Ach, du meinst wie in folgendem Beispiel?
    a[] wird nur in Zeile 008 verwendet, danach nicht mehr. Nach deiner Theorie verbraucht a[] ab Zeile 009 keinen Speicher mehr auf dem Stack -- schliesslich wird die Variable a[] ja nicht mehr verwendet?

    001 #define einMegabyte 1024*1024
    002 int main()
    003 {
    004   int a[einMegabyte];
    005   int i;
    006 
    007   for(i=0; i<einMegabyte-1; ++i)
    008     a[i]=1337;
    009 
    00a   ...
    00b   hier steht dann noch viel mehr Quellcode
    00c   aber a[] wird nicht mehr verwendet
    00d   ...
    00e   return 0;
    00f }
    

    Ich hatte etwas von am Ende jeden Blockes gesagt, also leider erst nach dem Ende von main().

    Und zu Descartes, natürlich würde ich kein 5kb Feld im Stack allokieren. Aber in einer Vielzahl von Fällen weiß man wieviel Platz man maximal benötigt und da sollte man auch mit Stack-SPeicherobjekten arbeiten finde ich. malloc um des malloc Willens ist Quatsch und kann das Programm verlangsamen und macht es schwieriger zu warten, denn man sollte ja auch immer nachprüfen, ob das denn alles so geklappt hat. Also immer schon ein if und im Fehlerfall aufräumen etc.

    Mich würde interessieren, wie groß denn der Netzwerkpuffer war?

    Gruß Tobias



  • tobidope schrieb:

    Hast du schon mal überlegt, was bei einem Funktionsaufruf passiert? Es müssen die Rücksprungadresse und alle lokalen Variablen gespeichert werden. Wo wohl?

    Ich hab gefragt, wieso du der Meinung bist, dass man den Stack NUR mit Rekursion sprengen kann. Bitte erst lesen, dann denken, dann posten.



  • Bashar schrieb:

    tobidope schrieb:

    Hast du schon mal überlegt, was bei einem Funktionsaufruf passiert? Es müssen die Rücksprungadresse und alle lokalen Variablen gespeichert werden. Wo wohl?

    Ich hab gefragt, wieso du der Meinung bist, dass man den Stack NUR mit Rekursion sprengen kann. Bitte erst lesen, dann denken, dann posten.

    Vielleicht habe ich mich etwas ungenau ausgedrückt. Ich habe nicht nur gesagt, sondern real nur. Natürlich kann das Anlegen eines char a[1024*1024] zu Problemen ja nach Architektur, Compiler - Linker und Betriebssystem geben, aber mir ist noch nie ein Programm abgestürzt wegen einer solchen Sache, da ich dies auch nicht machen würde. Stack-Overflow bei Funktionsaufrufen kann aber durchaus passieren. Aber für ein 20 oder 300 Byte grosses Feld malloc aufzurufen ist in meinen Augen Schwachsinn.

    Gruß Tobias



  • tobidope schrieb:

    Vielleicht habe ich mich etwas ungenau ausgedrückt.

    Ich empfinde "Erzähl bitte keinen Mist." nicht als ungenau. Wenn du dich ungenau ausdrücken willst, schmeiß nicht von vornherein so eine Stinkbombe in die Runde.

    Ich habe nicht nur gesagt, sondern real nur. Natürlich kann das Anlegen eines char a[1024*1024] zu Problemen ja nach Architektur, Compiler - Linker und Betriebssystem geben

    Eben. Kein Mist. Wenn der Stack nur 64k hat, kann das ganz schnell gehen. Der 8051 Microcontroller hat nur 128 Bytes Stack maximal!



  • Bashar schrieb:

    tobidope schrieb:

    Vielleicht habe ich mich etwas ungenau ausgedrückt.

    Ich empfinde "Erzähl bitte keinen Mist." nicht als ungenau. Wenn du dich ungenau ausdrücken willst, schmeiß nicht von vornherein so eine Stinkbombe in die Runde.

    Ich habe nicht nur gesagt, sondern real nur. Natürlich kann das Anlegen eines char a[1024*1024] zu Problemen ja nach Architektur, Compiler - Linker und Betriebssystem geben

    Eben. Kein Mist. Wenn der Stack nur 64k hat, kann das ganz schnell gehen. Der 8051 Microcontroller hat nur 128 Bytes Stack maximal!

    Hast du dir denn auch angesehen auf was ich geantwortet habe? Es ging dabei um das Anlegen eines char-Feld mit 100 Zeichen. Und in 99 von 100 Fällen macht man das nicht unbedingt mit malloc. Es ist fehleranfällig und unter Umständen langsamer. Es sei denn man spart sich das überprüfen des Rückgabewertes. Verwendet dein C-Compiler auf einem Microcontroller den nur ein Subset von ISO-C oder unterstützt er es komplett?

    Gruß Tobias



  • tobidope schrieb:

    Hast du dir denn auch angesehen auf was ich geantwortet habe? Es ging dabei um das Anlegen eines char-Feld mit 100 Zeichen.

    es geht hier aber um das anlegen eines 1.3 millionen Zeichen grossen Feldes.



  • Shade Of Mine schrieb:

    tobidope schrieb:

    Hast du dir denn auch angesehen auf was ich geantwortet habe? Es ging dabei um das Anlegen eines char-Feld mit 100 Zeichen.

    es geht hier aber um das anlegen eines 1.3 millionen Zeichen grossen Feldes.

    Ich habe mich aber explizit auf

    cppguru schrieb:

    wenn du schreibst
    char foo[100];
    wird ein Array von chars am STACK angelegt

    wenn du das ganze hingegen mit new machst
    char *foo = new char(100);
    wird ein Array von chars im HEAP angelegt.

    Am Stack hast du dann schnell nen overflow, aber im Heap (RAM) nicht!

    mfG
    cppguru

    bezogen. Es tut mir leid, dass man in Foren keine Subthreads aufmachen kann, aber das konnte ich so nicht stehen lassen, weil es so einfach nicht stimmt. Natürlich kann man in keiner real existierenden C-Implementation beliebig große Elemente im Stack anlegen, aber in keinem ISO- oder ANSI-Standard steht etwas von Stack oder Heap. Und wir reden hier von ANSI-C. Dachte ich zumindest. Was ist denn deine Meinung bzgl. Anlegen von Feldern?

    Gruß Tobias



  • tobidope schrieb:

    Hast du dir denn auch angesehen auf was ich geantwortet habe?

    Ups, bin bei dem "Mist" um ein Posting verrutscht.

    Es ging dabei um das Anlegen eines char-Feld mit 100 Zeichen. Und in 99 von 100 Fällen macht man das nicht unbedingt mit malloc. Es ist fehleranfällig und unter Umständen langsamer.

    Es ist unter Garantie immer langsamer (ausser der Compilerhersteller treibt Schabernack)

    Verwendet dein C-Compiler auf einem Microcontroller den nur ein Subset von ISO-C oder unterstützt er es komplett?

    Es ist eine "Freestanding Implementation" wie im Standard gefordert, zumindest soweit ich das überblicken kann.



  • Bashar schrieb:

    tobidope schrieb:

    Hast du dir denn auch angesehen auf was ich geantwortet habe?

    Ups, bin bei dem "Mist" um ein Posting verrutscht.

    Es ging dabei um das Anlegen eines char-Feld mit 100 Zeichen. Und in 99 von 100 Fällen macht man das nicht unbedingt mit malloc. Es ist fehleranfällig und unter Umständen langsamer.

    Es ist unter Garantie immer langsamer (ausser der Compilerhersteller treibt Schabernack)

    Verwendet dein C-Compiler auf einem Microcontroller den nur ein Subset von ISO-C oder unterstützt er es komplett?

    Es ist eine "Freestanding Implementation" wie im Standard gefordert, zumindest soweit ich das überblicken kann.

    Aber du stimmst mir schon zu, dass wenn möglich Stack-Variablen eleganter und schneller sind. Mir ist schon klar, dass man um portabel zu sein, gewisse Größen nicht überschreiten sollte. Aber ein Stack von 128k wird wohl fast überall sein. Und wenn man nicht zu tiefe Funktionsaufrufshierarchein hat, dann kann man sich damit nur das Leben leicht machen.

    Gruß Tobias



  • Jo da stimm ich mit dir überein.


Anmelden zum Antworten