Warum so häufig malloc



  • Ich komme aus der Großrechnerwelt - VSE dann MVS nun Z/OS und programmiere seit
    Jahrzehnten in Cobol, bez Assembler, wenns systemnah sein soll. In diesen Sprachen wird - außer bei Assembler ab und an in keiner Weise manuell Speicher angefordert. Ich habe mir anhand des GNU-C-Tutorials nun selbst C beigebracht und auch schon viele Anwendungen selbst geschrieben, die auch problemlos funktionieren - Von einer Pferdeverwaltung mit Buchungssystem, grafischer Oberfläche mit der GRAPHAPP-Lib und Postgresql-Datenbank als Basis - und auch hier brauchte ich bisher so gut wie nie malloc - außer bei der GraphAPP für die Listbox-Pointer. Normalerweise weiß man ja, wie lange Felder sein können und zur SIcherheit gibt es ja auch strncpy anstatt strcpy und snprinft usw um die Längen zu begrenzen. Ist das mit dem Malloc eigentlich mehr Mode oder stehen da auch Perfomance-Gründe dahinter ? Selbst eine maschinelle Connection-Steuerung für den Jack-Sound-Daemon habe ich ohne malloc realisiert. Ist halt nur mal so ne Frage an die langjährigen C-Praktiker.
    Ach ja - programmieren tue ich unter Debian-Linux squeeze.



  • pferdefreund schrieb:

    Normalerweise weiß man ja, wie lange Felder sein können [...]

    Ist das so?



  • Vorweg sollten wir uns darüber einig sein, daß globale Arrays und lokale static-Arrays meistens panne sind.

    Antwort: Um den Stack-Speicher klein zu halten! Der ist auf 32-Bittern oft auf nur 1M begrenzt.
    So ein malloc wird wohl weniger als 200 Takte fressen. Macht bei einem Array mit 10000 Elementen, von denen jedes mit mindestens 10 Takten angefaßt wird (irgendwas wird man darauf ja schon rechnen wollen), nur 0.2% der Laufzeit aus.
    Das Array auf dem Stack (muss übrigens nichtmal vorher eine bekannte Größe haben, Stichwort http://en.wikipedia.org/wiki/Variable-length_array ) kostet nur einen Takt zum Allokieren. Das sind 0.0%. Das sind nur 0.2% Unterschied also völlig egal.



  • Man lernt halt immer was dazu. Mit Stack usw hatte ich bisher in der IBM-Großrechnerwelt nie was am Hut und meine eigenen C-Anwendungen funktionieren alle problemlos - aber ich werde dann wohl zukünftig, wenns mal was grosses werden soll, wohl auch mehr mit malloc arbeiten. Wie gesagt, ich kenne das und verwende das auch ab und an - aber nicht so oft, wie man es in vielen kleinen Beispielen sieht.
    Und was die Feldlängen angeht - da muss man sich in der Z/OS-Welt immer schon vor dem Programmieren Gedanken machen, weil hier die Strings im Regelfall in der Länge begrenzt sind und der Bufferoverflow ist selbst bei Assembler auf dieser Hardware ein Fremdwort. ein mvc a,b überträgt b nach a und wenn a kleiner ist,
    wird eben abgeschnitten. Bei Cobol ist es genauso. Also überlegt man vorher, wie lange ein Feld sein kann und prüft das gleich bei der Eingabe.



  • Angenommen du würdest z.B. sowas wie MS Word programmieren wollen, wie lang würdest du den Buffer für den Text machen? 😉



  • pferdefreund schrieb:

    wird eben abgeschnitten. Bei Cobol ist es genauso.

    Naja, wenn man ein Unterprogramm aufruft, und in diesem einen Parameter zu lang definiert, dann wird dort zwar auch abgeschnitten, aber beim Aufrufer hat man dann schon Speicher überschrieben, was im günstigsten Fall zu einem 0C4 führt.

    pferdefreund schrieb:

    Also überlegt man vorher, wie lange ein Feld sein kann

    Andersrum:
    Man muss vorher (in COBOL) überlegen, wie lang das Feld sein kann, weil es gar keine Möglichkeit der dynamischen Verarbeitung gibt (ich kenne zumindest keine).
    Wenn man zum Beispiel eine Datei einliest, muss die maximale Zeilenlänge bekannt sein. In einem C-Programm ist das nicht erforderlich.



  • unter der IBM-Architektur gibt es im Regelfall eh nur satzorientierten IO
    Variabel lange felde gehen auch in Cobol
    so ala
    01 feld
    05 chars occurs 100 pic x(001) depending on zaehlfeld.

    Das kann sogar schon der alte COBOL-68-Compiler den ich unter MVS 3.8j
    benutze (Im Hercules GRoßrechner-Emulator). Es gibt nichts schöneres wie einen echten Mainframe auf em PC zu Hause. - und der Clou - Programme die man auf dem ca 35 Jahre alten System entwickelt laufen auf der heutigen Z/OS ohne !!!
    Neukompilieren oder linken. Das ist Investitionssicherheit - da kommt weder Linux und Windows erst recht nicht mit. In meiner ca 30 jährigen EDV-Zeit habe ich noch keinen Anbieter erlebt, der solche Zuverlässigkeit bieten kann, wie ne Z/OS, S/370, 4381 und wie die Kisten alle heißen. Wir haben heute noch in unserem Unternehmen über 20 Jahre alte Programme produktiv im Einsatz - aber das gehhört hier eigentlich nicht mehr hin.
    Und was das mit der Textverarbeitung angeht - da nimmt man variabel lange Sätze mit Zeilenzähler als Bestandteil des Keys - hab ich selbst schon mal innerhalb der CICS-Umgebung programmiert - eine Textverarbeitung für die Fachabteilung mit Variablenergänzung über eine IMS-Datenbank.



  • pferdefreund schrieb:

    Und was das mit der Textverarbeitung angeht - da nimmt man variabel lange Sätze mit Zeilenzähler als Bestandteil des Keys - hab ich selbst schon mal innerhalb der CICS-Umgebung programmiert - eine Textverarbeitung für die Fachabteilung mit Variablenergänzung über eine IMS-Datenbank.

    Mit anderen Worten: Man hacked sich sowas wie malloc() irgendwie zusammen!? 😉



  • ...



  • pferdefreund schrieb:

    unter der IBM-Architektur gibt es im Regelfall eh nur satzorientierten IO
    Variabel lange felde gehen auch in Cobol
    so ala
    01 feld
    05 chars occurs 100 pic x(001) depending on zaehlfeld.

    Das ist nicht variabler als

    01 chars pic x(100).
    

    Beide Male gehen maximal 100 rein ... und der Compiler reserviert auch beide Male die 100 Byte.



  • malloc() und ordentlich verwendete free()s dienen auch der Stabilität der SW, weil
    man dadurch nicht Gefahr läuft, dass man sich mal in der Schätzung der zu erwarteten Arraygrößen verschätzt.
    Wenn das Programm mit beliebigen Größen umgehen kann, dann stürzt es wegen übergroßen Daten nur dann ab, wenn der Speicher des Computers sowieso nicht mehr ausreicht.



  • hilft stabilität schrieb:

    malloc() und ordentlich verwendete free()s dienen auch der Stabilität der SW, weil
    man dadurch nicht Gefahr läuft, dass man sich mal in der Schätzung der zu erwarteten Arraygrößen verschätzt.
    Wenn das Programm mit beliebigen Größen umgehen kann, dann stürzt es wegen übergroßen Daten nur dann ab, wenn der Speicher des Computers sowieso nicht mehr ausreicht.

    Auch ich komme aus der Mainframe Welt und habe mir C selbst beigebracht und auch erfolgreich diverse C Projekte umgesetzt. Ich finde eigentlich, dass C und Cobol gar nicht so wit auseinander sind. Unter anderem eben der malloc und die gesamte Stringbearbeitung.
    Man ist am Anfang tatsächlich auf Grund der Tuts und Fachbücher verführt, jedes Byte mit malloc anzufordern. Was soll das?? Wenn ich weiss, dass beispielsweise mein dynamisches SQL Statement im Maximalfall 5000 Bytes gross werden kann, warum soll ich mich dann mit mallocs rumquälen und nicht gleich

    char sqlstmt[5000];
    

    codieren.
    Aber das ist ja - jedenfalls in meiner C Literatur - bei C Profis verpöhnt.
    Warum eigentlich??



  • Weil es nicht skaliert (bezüglich Länge des SQL-Statements).



  • malloc ist für die Fälle gedacht, wo du eben nicht von vornherein weißt, wie lang etwas werden kann oder die zu erwartende Länge zu stark variiert, als dass eine fixe Größe praktikabel wäre...



  • hilft stabilität schrieb:

    malloc() und ordentlich verwendete free()s dienen auch der Stabilität der SW, weil
    man dadurch nicht Gefahr läuft, dass man sich mal in der Schätzung der zu erwarteten Arraygrößen verschätzt.

    Inwiefern dient dies der Stabilität? Wenn mein Array "voll" ist, dann ist es voll, deswegen sollte ein Programm ja nicht abstürzen. Und um Überlaufchecks kommt man ja auch mit malloc nicht herum.

    hilft stabilität schrieb:

    Wenn das Programm mit beliebigen Größen umgehen kann, dann stürzt es wegen übergroßen Daten nur dann ab, wenn der Speicher des Computers sowieso nicht mehr ausreicht.

    Also doch nicht so stablilitätsdienlich...



  • Tim schrieb:

    hilft stabilität schrieb:

    malloc() und ordentlich verwendete free()s dienen auch der Stabilität der SW, weil
    man dadurch nicht Gefahr läuft, dass man sich mal in der Schätzung der zu erwarteten Arraygrößen verschätzt.

    Inwiefern dient dies der Stabilität? Wenn mein Array "voll" ist, dann ist es voll, deswegen sollte ein Programm ja nicht abstürzen. Und um Überlaufchecks kommt man ja auch mit malloc nicht herum.

    Das Array wird ja nicht zu voll, wenn es dank malloc an die zu erwartenden Daten dynamisch angepaßt wird.

    Sollte sich die Größe später noch ändern, dann mußt du natürlich dynamisch die Größe wieder anpassen, das Array also vergrößern und das in deinem Programmcode berückschtigen. Das ist ja klar.

    hilft stabilität schrieb:

    Wenn das Programm mit beliebigen Größen umgehen kann, dann stürzt es wegen übergroßen Daten nur dann ab, wenn der Speicher des Computers sowieso nicht mehr ausreicht.

    Also doch nicht so stablilitätsdienlich...

    Versuch doch mal ein Programm mit einem zur Compilezeit festgelegten statischen Array zu starten, dass so groß oder größer ist, wie dein verfügbarer Arbeitsspeicher.

    Bei malloc() kannst du hier wenigstens mit Fehlerbehandlungsroutinen auf den mangelnden Speicherplatz reagieren, während dein statisches Array nichtmal in den vom Compilier von Haus aus definierten Stack paßt.



  • hilft stabilität schrieb:

    Tim schrieb:

    hilft stabilität schrieb:

    malloc() und ordentlich verwendete free()s dienen auch der Stabilität der SW, weil
    man dadurch nicht Gefahr läuft, dass man sich mal in der Schätzung der zu erwarteten Arraygrößen verschätzt.

    Inwiefern dient dies der Stabilität? Wenn mein Array "voll" ist, dann ist es voll, deswegen sollte ein Programm ja nicht abstürzen. Und um Überlaufchecks kommt man ja auch mit malloc nicht herum.

    Das Array wird ja nicht zu voll, wenn es dank malloc an die zu erwartenden Daten dynamisch angepaßt wird.

    Sollte sich die Größe später noch ändern, dann mußt du natürlich dynamisch die Größe wieder anpassen, das Array also vergrößern und das in deinem Programmcode berückschtigen. Das ist ja klar.

    Natürlich ist das klar. Ich fragte auch nach der angeblich höheren Stabilität, aber ich denke wir haben einfach eine andere Definition von Stabilität...

    hilft stabilität schrieb:

    hilft stabilität schrieb:

    Wenn das Programm mit beliebigen Größen umgehen kann, dann stürzt es wegen übergroßen Daten nur dann ab, wenn der Speicher des Computers sowieso nicht mehr ausreicht.

    Also doch nicht so stablilitätsdienlich...

    Versuch doch mal ein Programm mit einem zur Compilezeit festgelegten statischen Array zu starten, dass so groß oder größer ist, wie dein verfügbarer Arbeitsspeicher.

    Ich nehme an der Linker wird versagen. Fehler zur Compilezeit, bei malloc hingegen Fehler zur Laufzeit.

    hilft stabilität schrieb:

    Bei malloc() kannst du hier wenigstens mit Fehlerbehandlungsroutinen auf den mangelnden Speicherplatz reagieren, während dein statisches Array nichtmal in den vom Compilier von Haus aus definierten Stack paßt.

    Statisches Array? Stack? Alles klar...



  • Tim schrieb:

    hilft stabilität schrieb:

    Tim schrieb:

    hilft stabilität schrieb:

    malloc() und ordentlich verwendete free()s dienen auch der Stabilität der SW, weil
    man dadurch nicht Gefahr läuft, dass man sich mal in der Schätzung der zu erwarteten Arraygrößen verschätzt.

    Inwiefern dient dies der Stabilität? Wenn mein Array "voll" ist, dann ist es voll, deswegen sollte ein Programm ja nicht abstürzen. Und um Überlaufchecks kommt man ja auch mit malloc nicht herum.

    Das Array wird ja nicht zu voll, wenn es dank malloc an die zu erwartenden Daten dynamisch angepaßt wird.

    Sollte sich die Größe später noch ändern, dann mußt du natürlich dynamisch die Größe wieder anpassen, das Array also vergrößern und das in deinem Programmcode berückschtigen. Das ist ja klar.

    Natürlich ist das klar. Ich fragte auch nach der angeblich höheren Stabilität, aber ich denke wir haben einfach eine andere Definition von Stabilität...

    Vermutlich liegt der Grund ultimativ in der Plattform. PC Programme laufen auf vielen unterschiedlichen Rechner mit einer großen Palette an verschiedener Hardware. Für das SQL Beispiel bedeutet das:
    Warum sollte ich Leuten mit schwachen Rechnern den Zugang zu meinem Programm verwehren, weil es auf die "maximal denkbaren Speicherverbrauch" designt wurde, obwohl im Durchschnitt der Normalnutzer vielleicht nur einen Bruchteil davon wirklich benötigt (z.B. weil er halt nur 1000 Zeichen lange SQL Statements hat)?



  • malloc ist nun einmal eine dynamische Anforderung von Speicherplatz, der auf allen Plattformen stets begrenzt ist, auch auf Grossrechnern.
    Man fordert den Speicherplatz während der Laufzeit an und gibt ihn bei Bedarf wieder frei. Das sollte auch einem COBOL-Programmierer soweit klar sein.
    Für einfache in der Länge bekannte Dinge nutzt man das besser nicht, nur für wesentliches mit tatsächlich völlig unbekannter Länge.

    Wer etwas bequemeres haben möchte, wählt einen anderen Compiler als C mit besserer Unterstützung durch Objekte und darauf anwenbare Methoden.



  • hilft stabilität schrieb:

    Wenn das Programm mit beliebigen Größen umgehen kann, dann stürzt es wegen übergroßen Daten nur dann ab, wenn der Speicher des Computers sowieso nicht mehr ausreicht.

    Wenn malloc NULL liefert und das Programm deshalb abstürzt, dann liegt das am Programmierer.


Anmelden zum Antworten