Warum so häufig malloc
-
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 gleichchar 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.
-
berniebutt schrieb:
malloc ist nun einmal eine dynamische Anforderung von Speicherplatz, der auf allen Plattformen stets begrenzt ist, auch auf Grossrechnern. ...
Macht ja auch Sinn, weil irgendwann der Speicher voll ist und irgendwann die Festplatte oder der logische Speicherraum. Viele von uns schreiben Code aufgrund des Glaubens, der Speicher wäre unendlich - aber es ist ein Irrglaube.
Also die Rückgabewerte von malloc/realloc haben durchaus ihren Sinn.
@edit: Natürlich meinte ich die Prüfung auf NULL
-
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.
Wenn du die Daten dagegen im RAM hältst, dann läuft das Ding halt 100x schneller.
Versuch mal einen Compiler mit "fixed-length + DB" zu implementieren.
Das wird schon irgendwie gehen, nur wird der so langsam sein, dass keiner damit arbeiten mag.
-
Morle schrieb:
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)?und
berniebutt schrieb:
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.
Nicht ganz. Wenn ich auf dem Mainframe ein Batchprogramm ausführe, also ein Programm, das keinen Bildschirmdialog hat, ist das in der Regel ein Job, der je nach Systemlast zwischen 1-15 Min "elapsed time" (es gibt auch Langläufer) und ein paar Sec. "CPU Time" verbratet. Sprich: Hier wird das Programm vom Batchenvironment gesteuert und bekommt nur soviel an Ressourcen (Storage, CPU, Start I/O usw), wie verfügbar sind, ohne das Gesamtsystem zu stressen.
Anders sieht es im Online Transaction Environment aus. Im CICS etwa muss ein Programm reusable programmiert werden. Das heisst sehr vereinfacht ausgedrückt, dass das System via einer "Linkage-Section" den Storage zur Verfügung stellt. Um das muss sich der Programmierer i.d.R. nicht kümmern (allenfalls TS- oder TD-Queues), da ihm diese Arbeit ein Preprocesser abnimmt und den Code generiert. Eigentlich schlau...
der Programmierer kann so beim Speichermanagement keine Fehler machen...
Ich könnte jetzt noch mehr Szenarien aufzählen - aber dieses Thema füllt ganze Schrankwände mit IBM-Literatur und kann hier nur oberflächlich angekratzt werden.
Klar, man kann so etwas nicht mit einem Windows oder Linux vergleichen. Und die Argumentation mit schwacher Hardware hat mich eigentlich überzeugt, warum man mallocs und reallocs benötigt.
Ach ja, wenn man auf dem Mainframe Assembler programmieren muss, gibts auch einen "Getmain" resp. "Freemain".
-
Das heisst für mich: Ihr macht heute auf Grossrechnern immer noch diese Klimmzüge mit Batchdaten = Stapelverarbeitung nur eben ohne Lochkarten?
Aber erstaunlich, dass jemand von COBOL auf C umsteigen möchte. Für mich sind das zwei verschiedene Welten!
-
berniebutt schrieb:
Das heisst für mich: Ihr macht heute auf Grossrechnern immer noch diese Klimmzüge mit Batchdaten = Stapelverarbeitung nur eben ohne Lochkarten?
So ist es. Ich bin zwar nicht Cobolfreak, aber ich weiß aus Erfahrung, dass jede Deiner Steuererklärungen und -bescheide sowie vermutlich auch jede Überweisung bei Deiner Bank in Form von einer elektronischen Lochkarte durch so ein Batchsystem läuft
Aber erstaunlich, dass jemand von COBOL auf C umsteigen möchte. Für mich sind das zwei verschiedene Welten!
Genau das sieht man immer wieder, wenn Leute aus dem COBOL-Umfeld nach ein- bis zweiwöchigen C- oder Java-Umsteigerkursen anfangen zu programmieren. Eine Klasse, 200 statische Variablen und eine Methode mit 600 Zeilen Code.
-
Ein Nachteil an statischen Array's ist, das die Größe eines Array's immer durch den Worst-Case Szenario festgelegt wird, s.d. der Speicherverbrauch im Best-Case der Speicherverbrauch im Wort-Case ist. Bei dynamischen Array's ist dies nicht der Fall; jedoch benötigen diese einen Verwaltungsaufwand.
Bsp:
typedef struct { double x; double y; double z; char Comment[80]; } tPoint; typedef struct { tPoint Points[1000]; size_t Size; } tPolygon; typedef struct { tPolygon Polygons[1000]; size_t Size; } tPolygonArray;
Ein tPolygonArray belegt bei mir satte 104.008.008 Bytes, wobei die Grenzen definitiv nicht groß sind. Auf kleinen, schwachen Rechnern hast du da ein Problem, denn diese cirka 100 MByte pro PolygonArray belegst du immer! Die kannst du nicht mehr auf den Stack schieben, sondern die must du global legen.
Dynamische Datenstrukturen sind ohne malloc() schwer zu realisieren.
-
Also 2 verschiedene Welten sind das nicht wirklich - auch in Cobol kann man in Funktionen auslagern, die hier halt perform heißen. Man kann das sogar im Assembler mit balr und br. Die Sprache ist eigentlich nur ein Syntaxproblem.
Ich habe jetzt von PL/1, Cobol, Assembler, Rexx, Abap, C , bash-Scripting so einiges in den letzten 30 Jahren durch und das Hautproblem ist nicht die Sprache, sondern der Weg ein Problem so zu lösen, dass man nach über 6 Monaten noch weiss, warum man was gemacht hat. Im Endeffekt wird eh - außer bei interpretierten Sprachen - alles Assembler.
-
pferdefreund schrieb:
Also 2 verschiedene Welten sind das nicht wirklich - auch in Cobol kann man in Funktionen auslagern, die hier halt perform heißen.
Du hast aber bei performs auf Paragrafen/Sections keine lokalen Variablen.
Und wenn ich mich richtig erinnere, habe ich mal auf einem IBM-Mainframe versucht, eine Section rekursiv zu performen, auch das hat glaube ich nicht funktioniert.Das in C oder C++ einfach zu lösende Problem:
Gib eine beliebige Anzahl an Buchstaben ein, berechne alle möglichen Wörter und gib sie aus, habe ich in COBOL nicht hingekriegt, weil mir die Rekursion fehlte, mal abgesehen davon, dass man nicht beliebig viele Buchstaben zu einem Wort zusammenfügen kann, weil man eben nicht dynamisch Speicher anfordern kann.
-
pferdefreund schrieb:
2 verschiedene Welten sind das nicht wirklich ... kann das sogar im Assembler ... die Sprache ... nur ein Syntaxproblem ... habe jetzt ... den letzten 30 Jahren ... das Hautproblem ist nicht die Sprache ... 6 Monaten noch weiss, warum ... eh ... alles Assembler.
Blablabla. Der ein oder andere hier hat mehr Erfahrung, kann mehr Sprachen, ... Denkst du, dass wir keine Ahnung haben? Typisch Troll.
-
berniebutt schrieb:
Aber erstaunlich, dass jemand von COBOL auf C umsteigen möchte. Für mich sind das zwei verschiedene Welten!
Richtig. Meinen ersten Kontakt mit OO hatte ich vor etwa 20 Jahren. Da erzählte in einem Referat ein Referent vor versammelter Mannschaft (alles Hostprogrammierer) etwas von einem Tier von dem man eine Kuh, ein Pferd oder einen Ochsen ableiten könne. Diese können verschiedene Farben haben und verschiedene Zustände (laufen, stehen, traben usw) und das habe etwas mit Klassen, Attributen und Methoden zu tun - ach ja - und mit Bank - IT... Na klasse.
Einen ähnlichen Schwachsinn erzählte man uns dann in einer anderen Grossbank im Zusammenhang mit Java etwa 10 Jahre später.
Nun gut - ich habe dann während einer Projektpause quasi in einer einsamen Berghütte mir das ganze mal näher angeschaut.. Aha - dann wurde das schon klarer: Einfach andere Begriffe für Unterprogramme, Funktionen und Variable (passt nicht ganz - aber das soll langen). Zudem ein Ansatz der Instanzierung, den es in der alten Mainftame Welt so nicht gibt. Zum Glück muss ich damit meine Brötchen nicht verdienen.
Was damals hängen blieb war C, da es einen ähnlichen Ansatz der strukturierten Programmierung wie etwa Cobol oder PL/I hat. Hobbymässig klappen mitlerweile sogar schon GUI Programme.
So kommt man also als Cobolprogrammierer zu C...
-
Auch COBOL entwickelt sich weiter. Inzwischen gibt es mit Object COBOL sogar auch dort dynamische Speicheranforderung, Konstruktion, Destruktion uvm. Nur die Formulierung ist nach wie vor ein Graus.
Ich habe immer gesagt COBOL kann man lesen wie ein Buch, aber um es zu schreiben muss man Schriftsteller sein