malloc/calloc/realloc usw. wann ist es sinnvoll, wann nicht?



  • hi,
    hier gibts ja unterschiedliche ansichten zu dem thema. welche vorteile hat man durchs benutzen der dynamischen speicherverwaltung und wo liegen die nachteile?
    nwp2 und ich freuen uns auf eine rege diskussion.
    🙂



  • Na dann will ich mal nicht so sein.

    Beispiel Listen, Stacks, Buffer, Suchbäumen und ähnliches.
    Stellvertretend nehme ich mal einen int-Stack.
    Mallocvariante:

    struct intStack{
        struct intStackElement *first;
    };
    struct intStackElement{
        struct intStackElement *previous;
        int value;
    };
    void pushIntStack(struct intStack *is, int value){
        struct intStackElement *ise = malloc(sizeof(intStackElement));
        if (!ise){
            fprintf(stderr, "Out of memory!\n");
            return;
        }
        ise->value = value;
        ise->previous = is->fist;
        is->first = ise;
    }
    int popIntStack(struct intStack *is){
        if (!is->first) return NOINTVALUE;
        struct intStackElement *temp = is->first;
        is->first = is->first->previous;
        int value = temp->value;
        free(temp);
        return value;
    }
    

    Dagegen die mallocfreie Variante:

    void intStack(int *value, bool pop){
        const int bufferlength = 12345;
        static int buffer[12345];
        static int *position = buffer;
        if (pop){
            if (position==buffer) return NOINTVALUE;
            *value = position--;
        }
        else{ //push
            if (position-buffer==bufferlength) fprintf(stderr, "Buffer too small\n");
            else ++position = *value;
        }
    }
    void pushIntStack(int value){
        intStack(&value, false);
    }
    int popIntStack(){
        int value;
        intStack(&value, true);
        return value;
    }
    

    Ich hoffe mal ich habe keine allzu groben Fehler drin.

    Die Vorteile der Mallocvariante sind, dass man soviele ints speichern kann wie man Speicher hat und der Speicherverbrauch bei nicht-benutzen praktisch 0 ist.
    Man kann den intStack in einem Programm für sonstwas benutzen, selbst in 20 Jahren kann man sich 100GB RAM in den Rechner packen und ihn mit ints vollschreiben. Gleichzeitig kann man ihn auch nicht benutzen und er frisst kein Brot. Man kann zum Beispiel eine 1GB große int-Datenbank anlegen und einen zweiten Stack benutzen um die ersten 5 Primzahlen zu speichern.

    Die Nachteile sind, dass man 100% Speicheroverhead hat und es etwas CPU kostet.
    Sollte man wirklich in Speicherprobleme kommen kann man auch Blöcke benutzen und statt einem int 9 ints pro intStructElement speichern, das würde den Speicheroverhead auf 10% drücken, oder man nimmt 99 ints für 1% Speicheroverhead. Kostet natürlich 100*sizeof(int) Speicher für nur eine Zahl, aber 400Byte sind nicht wesentlich.

    Die Vorteile der mallocfreien Variante sind, dass es kaum CPU kostet und der Quellcode etwas kürzer ist.

    Die Nachteile sind:
    -Man hat nur einen Stack und kann keinen zweiten bauen, es sei denn man kopiert alle Funktionen und hängt eine 2 an. Dann hat man wieder das Problem dass man keinen dritten Stack haben kann usw. Bei 10 Stacks ist der Code riesig. Der Speicherverbrauch auch.
    -Man kann bufferlength keinen sinnvollen Wert zuweisen. Wenn man den intStack zu klein macht reicht er nicht, wenn er zu groß ist geht irgendwann der Speicher aus. Für die ~1GB-Datenbank sollte ich schon einen 2GB-Buffer anlegen und beten dass niemand auf die Idee kommt 3GB speichern zu wollen. Die 100GB int-Datenbank in 20 Jahren fällt natürlich flach. Meine 5 Primzahlen auch, 4GB Speicher hat mein Rechner nicht.
    -Wenn man sowas öfter benutzt, in mehreren Funktionen in einem größeren Projekt, dann kommt man leicht auf den 10 bis 100-fachen Speicherverbrauch und trotzdem verabschiedet sich das Programm weil irgendeiner der vielen Buffer zu klein geraten ist.

    Noch eine Anmerkung zu Speicher und CPU: Man kann relativ leicht den Rechenaufwand auf Kosten des Speicherverbrauchs verringern und andersrum. Meine CPU ist notorisch auf 0%. Dafür rattert die Festplatte und swapt RAM wie blöde. Selbst unter "Volllast" komme ich nur auf 50% CPU-Auslastung, Dualcore eben. Dafür hängt mein System ewig wenn ich ein im Hintergrund gebuffertes Youtube-Video abspielen will weil er sonstwieviel Kram umswapt. Ich würde jederzeit Speicher auf Kosten der Rechenleistung einsparen wollen. Die Zeit wo Rechenleistung knapp war und Speicher reichlich vorhanden war ist lange vorbei.

    Nehmen wir mal ein anderes Beispiel.
    Wir wollen PI auf 100 Stellen genau berechnen. Wir überlegen uns dass wir einfach 100 chars an Speicher nehmen.
    Mallocvariante:

    char *buffer = malloc(100);
    if (!buffer) fprintf(stderr, "Out of memory\n");
    

    Mallocfreie Variante:

    char buffer[100];
    

    Der Unterschied ist minimal. Malloc kostet etwas CPU, aber das wars dann auch schon. Ich würde spontan die mallocfreie Variante nehmen weil ich mir die eine Zeile Code mit dem Out of memory sparen wollen würde, aber wenn jemand hier malloc benutzt, naja, den paar tausend CPU-Zyklen heule ich nicht hinterher.

    Nachdem ich mich hier so ausgiebig ausgelassen habe was sich eh keiner durchliest kann mich bestimmt jemand aufklären wieso malloc böse ist und um jeden Preis verhindert werden muss.



  • nwp2 schrieb:

    Die Zeit wo Rechenleistung knapp war und Speicher reichlich vorhanden war ist lange vorbei.

    also man könnte ja schon mal schauen ob Rechenleistung und Speicher nicht direkt porpotional anwachsen (wenn das so heißt) also ich meine 1ghz 256mb 4ghz 1gb usw.

    also bei mir ist von allem immer zu wenig da 😃

    nwp2 schrieb:

    Die Vorteile der mallocfreien Variante sind, dass es kaum CPU kostet und der Quellcode etwas kürzer ist.

    also wenn ich jetzt 1000 ints brauch und hol mir die über einen malloc aufruf, ist das doch kein problem aber 1000 mallocs für 1000 ints ist schon ein beachtlicher overhead.

    man muß unterscheiden für welche plattform entwickelt wird und dann entscheiden ob ich vorher weiß was die function braucht, denn dann werd ichs kaum über malloc machen, anderen falls evtl. schon, bzw. hab ich doch dann gar keine andere wahl außer ich bau mir ne eigene malloc was ja auch ganz lustig ist aber auch nur wenn ich das einzige programm bin das gerade läuft.

    evtl. könnte man so als kleine faustregel festhalten

    größe zur compile zeit unbekannt -> malloc
    größe zur compile zeit bekannt -> kein malloc

    lg lolo



  • nwp2 schrieb:

    Nehmen wir mal ein anderes Beispiel.
    Wir wollen PI auf 100 Stellen genau berechnen. Wir überlegen uns dass wir einfach 100 chars an Speicher nehmen.

    ich denk du nimmst dann eher GMP statt 100 chars 😉 das arbeitet intern mit ints wenn ich nicht falsch lieg.

    nwp2 schrieb:

    Mallocvariante:

    char *buffer = malloc(100);
    if (!buffer) fprintf(stderr, "Out of memory\n");
    

    Mallocfreie Variante:

    char buffer[100];
    

    für mich kommt da nur die Mallocfreie Variante in frage also malloc(100) find ich paßt einfach nicht, hättest malloc(x) würds schon anders ausschauen 🙂



  • nwp2 schrieb:

    Die Vorteile der Mallocvariante sind, dass man soviele ints speichern kann wie man Speicher hat und der Speicherverbrauch bei nicht-benutzen praktisch 0 ist.

    naja, nicht wirklich. unter windoofs hat der heap eine anfangsgrösse (zwar nicht 'committed', sondern nur 'reserved'), was zwar keinen physikalischen speicher braucht, aber schonmal einige adressen im virtuellen adressraum kostet. ok, das ist nicht schlimm, aber z.b. bei den meisten embedded systemen gibt es kein virtuelles speichermanagement, da ist der heap einen fester speicherblock. es wird also sofort eine gehörige menge vom vorhandenen speicher abgezwackt, was extrem doof ist, weils speicher kostet, der u.u. garnicht benutzt wird.

    nwp2 schrieb:

    Man kann den intStack in einem Programm für sonstwas benutzen, selbst in 20 Jahren kann man sich 100GB RAM in den Rechner packen und ihn mit ints vollschreiben.

    das ist ein künstlich konstruiertes beispiel ohne praktische relevanz. wann braucht man jemals solche grossen stacks? in wahrheit doch verdammt selten, ne?

    nwp2 schrieb:

    Die Vorteile der mallocfreien Variante sind, dass es kaum CPU kostet und der Quellcode etwas kürzer ist.

    und dass sie 100% absolut zuverlässig und deterministisch ist. der speicher ist immer da, das programm kennt zu jedem zeitpunkt den füllstand. es gibt keine speicheranforderungen, die fehlschlagen können.

    nwp2 schrieb:

    Die Nachteile sind:
    -Man hat nur einen Stack und kann keinen zweiten bauen, es sei denn man kopiert alle Funktionen und hängt eine 2 an. Dann hat man wieder das Problem dass man keinen dritten Stack haben kann usw. Bei 10 Stacks ist der Code riesig. Der Speicherverbrauch auch. ...

    völlig falsch, du kannst es über eine struct machen, z.b:

    typedef struct stack
    {
      char *memory;      // zeigt auf den speicheranfang des stacks
      size_t size;       // grösse des speichers in bytes
      size_t stackptr;   // stackpointer
    } stack_t;
    

    ^^ und damit soviele stacks unterschiedlicher grösse managen wie du willst. und du brauchst dazu nur einen satz von stack-funktionen (init, push, pop).

    nwp2 schrieb:

    Nehmen wir mal ein anderes Beispiel.
    Wir wollen PI auf 100 Stellen genau berechnen. Wir überlegen uns dass wir einfach 100 chars an Speicher nehmen.

    ebenfalls kein malloc nötig, eigentlich noch nicht mal arrays. es gibt algorithmen, die berechnen die ziffern von PI einzeln oder stückchenweise auf beliebig viele stellen.

    nwp2 schrieb:

    char *buffer = malloc(100);
    if (!buffer) fprintf(stderr, "Out of memory\n");
    

    Mallocfreie Variante:

    char buffer[100];
    

    ^^ das z.b. ist ein absolutes 'antipattern'. sich temporären speicher von 100 bytes zu besorgen, und dafür 'malloc' zu bemühen, ist ohne sinn und verstand. ein lokales array (auf dem stack) ist in 99.999% der fälle das einfachste und sicherste.

    noobLolo schrieb:

    evtl. könnte man so als kleine faustregel festhalten
    größe zur compile zeit unbekannt -> malloc
    größe zur compile zeit bekannt -> kein malloc

    ich schlage diese regel vor: ist eine lösung ohne malloc möglich?
    ja -> auf malloc verzichten und sich freuen.
    nein -> nochmal genau nachdenken, denn die wahrscheinlichkeit ist hoch, dass man nicht zuende gedacht hat.
    🙂



  • ;fricky schrieb:

    naja, nicht wirklich. unter windoofs hat der heap eine anfangsgrösse (zwar nicht 'committed', sondern nur 'reserved'), was zwar keinen physikalischen speicher braucht, aber schonmal einige adressen im virtuellen adressraum kostet. ok, das ist nicht schlimm, aber z.b. bei den meisten embedded systemen gibt es kein virtuelles speichermanagement, da ist der heap einen fester speicherblock. es wird also sofort eine gehörige menge vom vorhandenen speicher abgezwackt, was extrem doof ist, weils speicher kostet, der u.u. garnicht benutzt wird.

    Das verstehe ich nicht. Deine mallocfreien Varianten kosten hundertfach speicher der zu 80% ungenutzt ist und zu 10% nicht reicht, aber die 20 Bytes auf dem Heap stören dich?

    ;fricky schrieb:

    das ist ein künstlich konstruiertes beispiel ohne praktische relevanz. wann braucht man jemals solche grossen stacks? in wahrheit doch verdammt selten, ne?

    So künstlich ist das garnicht. Natürlich wird dieser genaue Fall nie auftreten, aber nehmen wir mal Word. Die Programmierer nehmen sich ein Buffer, testen es mit 100 Zeilen Blödsinn getippe und stellen fest es geht alles und liefern aus. Dann kommt irgendwer auf die dumme Idee seine Diplomarbeit darauf zu schreiben, schreibt 10000 Zeilen und Word stürzt ab. Oder ein Strategiespiel, alle Einheiten funktionieren, dann treffen zwei Prospieler aufeinander, 2 riesige Armeen, eine große Schlacht, Buffer alle. Man kann einfach nicht vorhersehen wie intensiv bestimmte Strukturen benutzt werden und deshalb ist malloc bei unbekannter Speichergröße immer sicherer.

    nwp2 schrieb:

    Die Vorteile der mallocfreien Variante sind, dass es kaum CPU kostet und der Quellcode etwas kürzer ist.

    ;fricky schrieb:

    und dass sie 100% absolut zuverlässig und deterministisch ist. der speicher ist immer da, das programm kennt zu jedem zeitpunkt den füllstand. es gibt keine speicheranforderungen, die fehlschlagen können.

    Naja, so stimmt das nicht. Der Speicher ist immer da und genau da liegt das Problem. Man braucht den Speicher zu 90% garnicht, trotzdem muss er bereitgestellt werden. Ich habe noch ein Extrembeispiel: Wir installieren ein MMORPG, das ist eine Ausführbare Datei bestehend aus etwa 100kb Programm und einem je nach Spiel etwa 1-2GB großen Buffer wo die Spieldaten drin sind. Super. Man führt das Programm aus und 1-2GB werden in den RAM geladen. Ich habe aber nur 1GB, das heißt es wird ausgeswapt. Wir kopieren also 1-2GB Daten von der Festplatte in den RAM und von dort wieder auf die Festplatte. Das sorgt dafür dass der Rechner 10 bis 20 Minuten hängt und nicht ansprechbar ist. Speicher kostet enorm Zeit, dagegen ist malloc ein Witz.

    ;fricky schrieb:

    völlig falsch, du kannst es über eine struct machen, z.b:

    typedef struct stack
    {
      char *memory;      // zeigt auf den speicheranfang des stacks
      size_t size;       // grösse des speichers in bytes
      size_t stackptr;   // stackpointer
    } stack_t;
    

    ^^ und damit soviele stacks unterschiedlicher grösse managen wie du willst. und du brauchst dazu nur einen satz von stack-funktionen (init, push, pop).

    Aha. Du zeigst also mit allen Stacks auf denselben Speicher? Das geht nicht gut. Oder auf verschiedenen Speicher? Dann kommst du an malloc nicht vorbei.

    ;fricky schrieb:

    nwp2 schrieb:

    Nehmen wir mal ein anderes Beispiel.
    Wir wollen PI auf 100 Stellen genau berechnen. Wir überlegen uns dass wir einfach 100 chars an Speicher nehmen.

    ebenfalls kein malloc nötig, eigentlich noch nicht mal arrays. es gibt algorithmen, die berechnen die ziffern von PI einzeln oder stückchenweise auf beliebig viele stellen.

    Darum geht es doch nicht. Das war nur ein Beispiel dass man eine Struktur mal nicht exzessiv ausnutzt. Ich nehme mal lieber wieder Word als Beispiel. Ich möchte einen Brief ans Finanzamt schreiben mit einem Satz + Anrede drin. Und ich habe keine Lust ewig zu warten bis der 100MB Buffer geladen hat, weil Word nicht weiß, ob ich einen Einzeiler oder eine Diplomarbeit schreibe.
    Wobei das bei einer handvoll von Buffern vielleicht noch erträglich wäre, mal abgesehen davon dass ich immer hoffen muss nicht irgendeine schwachsinnige Grenze zu übertreten, aber wenn man das kontinuierlich mach, in jeder Funktion, da müssen doch Unmengen von ungenutzten Buffern anfallen. Ich glaube ich verstehe wie Eclipse auf 140MB kommt.

    nwp2 schrieb:

    char *buffer = malloc(100);
    if (!buffer) fprintf(stderr, "Out of memory\n");
    

    Mallocfreie Variante:

    char buffer[100];
    

    ;fricky schrieb:

    ^^ das z.b. ist ein absolutes 'antipattern'. sich temporären speicher von 100 bytes zu besorgen, und dafür 'malloc' zu bemühen, ist ohne sinn und verstand. ein lokales array (auf dem stack) ist in 99.999% der fälle das einfachste und sicherste.

    Streitbar. Es hat den Sinn dass man sich 100 Bytes beim Programmladen spart. Außerdem während das Programm läuft. Vor allem wenn die 100 Bytes nur beim Programmstart benötigt werden um irgendwas zu initialisieren und dann nie wieder ist das durchaus sinnvoll. Ich würde es auch nicht machen, aus Faulheit, aber richtig wäre es.

    noobLolo schrieb:

    evtl. könnte man so als kleine faustregel festhalten
    größe zur compile zeit unbekannt -> malloc
    größe zur compile zeit bekannt -> kein malloc

    ;fricky schrieb:

    ich schlage diese regel vor: ist eine lösung ohne malloc möglich?
    ja -> auf malloc verzichten und sich freuen.
    nein -> nochmal genau nachdenken, denn die wahrscheinlichkeit ist hoch, dass man nicht zuende gedacht hat.
    🙂

    Es kommt wohl drauf an was man unter Lösung versteht. Es erinnert mich an die Anfangsphilosophie von Unix. "Wenn ein Programm zu 80% tut was es soll dann reicht das". Speicher war halt knapp. Heute habe ich und viele andere den Anspruch, dass ein Programm mehr als nur Trivialbeispiele beherrscht.
    Meine Variante:
    Größe zur Compilezeit unbekannt -> malloc
    Speicher wird nur kurzfristig benötigt -> malloc
    Speicher wird immer während des ganzen Programms gebraucht und die Größe ist bekannt -> kein malloc
    Obwohl man sich bei der letzten Regel schon überlegen könnte, dass das malloc praktisch nichts kostet und man der Einfachheit halber einfach immer malloc nimmt, es sei denn es geht wirklich nicht anders.

    noobLolo schrieb:

    nwp2 schrieb:

    Die Zeit wo Rechenleistung knapp war und Speicher reichlich vorhanden war ist lange vorbei.

    also man könnte ja schon mal schauen ob Rechenleistung und Speicher nicht direkt porpotional anwachsen (wenn das so heißt) also ich meine 1ghz 256mb 4ghz 1gb usw.

    also bei mir ist von allem immer zu wenig da 😃

    Ok, ich habe mich schlecht ausgedrückt. Speicher und Rechenleistung wachsen schon ungefähr proportional an, aber die Zugriffszeit auf den Speicher bleibt gleich. Festplatten sind seit 30 Jahren nicht wesentlich schneller geworden (man hats von etwa 10MB/s auf ~20-30MB/s geschafft, aber viel mehr geht nicht. Im Vergleich dazu 1MHz->3GHz ist doch schon ein Unterschied). Register sind Flipflops und schneller gehts einfach nicht. Man kann problemlos einen Rechner mit 10TB Festplatte und 100GB RAM mit eine Grafikkarte mit 10GB RAM bauen und einen 10GHz Prozessor spendieren. Aber der ist nicht wesentlich schneller als ein Aldi-PC, weil der nur auf den Speicher wartet. Die Z10, IBM's aktueller Mainframe, das beste vom besten hat lächerliche 4.4GHz. Mein alter Laptop hat 1.6GHz, damit komme ich nicht ganz an den Mainframe ran, aber so weit weg ist das nicht. Und es ist nicht so dass die nicht mehr können, Intel hat mal testweise einen Pentium 4 übertaktet, Intel-style. Man entferne den Kühler vom Prozessor, schraube ein Rohr oben drauf und schütte flüssigen Stickstoff rein und übertakte den Pentium 4 auf 10 GHz. Hat funktioniert. Das einzige Problem war, dass der 10GHz P4 nur minimal schneller als der 3GHz P4 war. Ich sags euch, Speicherminimierung ist die Zukunft, und mit malloc lässt es sich gut minimieren, mit festen Buffern nicht.

    nwp2 schrieb:

    Die Vorteile der mallocfreien Variante sind, dass es kaum CPU kostet und der Quellcode etwas kürzer ist.

    noobLolo schrieb:

    also wenn ich jetzt 1000 ints brauch und hol mir die über einen malloc aufruf, ist das doch kein problem aber 1000 mallocs für 1000 ints ist schon ein beachtlicher overhead.

    man muß unterscheiden für welche plattform entwickelt wird und dann entscheiden ob ich vorher weiß was die function braucht, denn dann werd ichs kaum über malloc machen, anderen falls evtl. schon, bzw. hab ich doch dann gar keine andere wahl außer ich bau mir ne eigene malloc was ja auch ganz lustig ist aber auch nur wenn ich das einzige programm bin das gerade läuft.

    Die Plattform beachte ich nie. Die einzige Plattform die ich habe ist mein Desktoprechner. Für nicht-Desktoprechner wie Handys gelten andere Regeln, davon habe ich aber keine Ahnung.



  • nwp2 schrieb:

    ;fricky schrieb:

    naja, nicht wirklich. unter windoofs hat der heap eine anfangsgrösse (zwar nicht 'committed', sondern nur 'reserved'), was zwar keinen physikalischen speicher braucht, aber schonmal einige adressen im virtuellen adressraum kostet. ok, das ist nicht schlimm, aber z.b. bei den meisten embedded systemen gibt es kein virtuelles speichermanagement, da ist der heap einen fester speicherblock. es wird also sofort eine gehörige menge vom vorhandenen speicher abgezwackt, was extrem doof ist, weils speicher kostet, der u.u. garnicht benutzt wird.

    Das verstehe ich nicht. Deine mallocfreien Varianten kosten hundertfach speicher der zu 80% ungenutzt ist und zu 10% nicht reicht, aber die 20 Bytes auf dem Heap stören dich?

    mich stört's z.b. wenn überhaupt ein heap da ist, obwohl er nicht ausgelastet wird. malloc-freie varianten verschwenden keinen speicher, sondern teilen den speicher sinnvoll auf. wenn ich z.b. einen buffer von 256 bytes anlege, dann bin ich mir sicher, dass ich soviel brauche. nicht mehr und nicht weniger.

    nwp2 schrieb:

    ...aber nehmen wir mal Word. Die Programmierer nehmen sich ein Buffer, testen es mit 100 Zeilen Blödsinn getippe und stellen fest es geht alles und liefern aus. Dann kommt irgendwer auf die dumme Idee seine Diplomarbeit darauf zu schreiben, schreibt 10000 Zeilen und Word stürzt ab.

    keine ahnung wie 'word' arbeitet, verbuggt ist es sowieso, aber um mal bei 'ner textverarbeitung zu bleiben: du brauchst nur 'nen screen-buffer (fester grösse) in dem du arbeitest. das riesige schriftstück befindet sich auf der platte und es muss immer nur ausschnittweise geladen werden. sowas konnte sogar schon 'wordstar' von anno knuck (auf alten CP/M-kisten die noch nicht mal 64kB RAM hatten).

    nwp2 schrieb:

    ;fricky schrieb:

    völlig falsch, du kannst es über eine struct machen, z.b:

    typedef struct stack
    {
      char *memory;      // zeigt auf den speicheranfang des stacks
      size_t size;       // grösse des speichers in bytes
      size_t stackptr;   // stackpointer
    } stack_t;
    

    ^^ und damit soviele stacks unterschiedlicher grösse managen wie du willst. und du brauchst dazu nur einen satz von stack-funktionen (init, push, pop).

    Aha. Du zeigst also mit allen Stacks auf denselben Speicher? Das geht nicht gut. Oder auf verschiedenen Speicher? Dann kommst du an malloc nicht vorbei.

    natürlich hat jeder stack seinen eigenen speicher. malloc brauchste überhaupt nicht dafür, können alles statische arrays sein. es sei denn, du brauchst 'ne variable anzahl an stacks, die du nach belieben neu anlegen oder löschen willst.

    nwp2 schrieb:

    nwp2 schrieb:

    char *buffer = malloc(100);
    if (!buffer) fprintf(stderr, "Out of memory\n");
    

    Mallocfreie Variante:

    char buffer[100];
    

    ;fricky schrieb:

    ^^ das z.b. ist ein absolutes 'antipattern'. sich temporären speicher von 100 bytes zu besorgen, und dafür 'malloc' zu bemühen, ist ohne sinn und verstand. ein lokales array (auf dem stack) ist in 99.999% der fälle das einfachste und sicherste.

    Streitbar. Es hat den Sinn dass man sich 100 Bytes beim Programmladen spart.

    die 100 bytes auf dem stack-frame sind absolut lächerlich, es sei denn du programmierst für 'nen 8-bitter (PIC oder sowas), zumal der speicher sowieso wieder frei wird, wenn die funktion verlassen wird. lokale variablen mit malloc anzulegen ist völlig sinnlos und hat *nicht den geringsten vorteil*

    nwp2 schrieb:

    Ich glaube ich verstehe wie Eclipse auf 140MB kommt.

    falls du 140MB RAM meinst, das ist der Java-heap, eine dynamische speicherverwaltung, die in den meisten fällen nur zum bruchteil genutzt wird. man kann ihn kleiner machen, allerdings ist Java auf einen heap angewiesen (im gegensatz zu C). soviel nur zur angeblichen speicherersparnis durch dynamische speicherverwaltung *fg*
    🙂



  • Ich würde ja new statt malloc nutzen.

    *Weicht Wurfgeschossen aus und haut ab*



  • also, ich sehe das ähnlich wie fricky. malloc ist einfach fehleranfehlig und lahm. Wenn ich die Speichergröße zur Compilezeit kenne, gibt es keinen vernünftigen Grund, malloc zu verwenden. Außerdem reserviert ein malloc(100) nicht zwangsläufig 100 Bytes sondern mehr. Das kann auf Dauer zu Speicherverschwendung führen. Jaja, mit 4GB-RAM reicht das locker. Desktop-PCs sind nicht die einziegen Systemen, die es gibt. Ich wage sogar zu vermuten, dass weltweit mehr embedded-systems laufen, als Desktop-PCs. Speicherschonend sollte man immer programmieren, egal für welche Plattform man entwickelt.



  • Icematix schrieb:

    Ich würde ja new statt malloc nutzen.

    meinste, dann kannste wenigstens auf das 'free()' verzichten? aber falls du's nicht gemerkt hast, hier ist das C- und nicht das Java- oder C#-forum *Gg*
    🙂



  • ;fricky schrieb:

    malloc-freie varianten verschwenden keinen speicher, sondern teilen den speicher sinnvoll auf.

    void einmal (void) {
    
     char buffer [10000];
     ...
    }
    
    void staendig (void) {
    
     char buffer [100];
     ...
    }
    
    int main (void) {
    
     staendig ();
     staendig ();
     ...
     staendig ();
     staendig ();
    
     einmal ();
    
    }
    

    ^^ Werden hier nicht bereits bei Programmstart mind. 10 KB Stack "reserviert", obwohl er in dieser Größe nur einmal gebraucht wird?



  • malloc(gerne) schrieb:

    Werden hier nicht bereits bei Programmstart mind. 10 KB Stack "reserviert", obwohl er in dieser Größe nur einmal gebraucht wird?

    nö, unter windosen z.b. bekommt jeder thread (per default) 1MB virtual memory für den stack verpasst. in funktionen werden kurzzeitig (solange sich das programm in der funktion befindet) von diesen 1MB speicher für lokale variablen abgezwackt. das geschieht übrigens nicht durch aufwendige algorithmen (wie bei malloc), sondern durch simples versetzen eines internen pointers.
    beispiel (wenn wir mal speicher für rücksprungadressen usw. ignorieren):

    void f1 (void) // braucht 100 bytes solange wir in der funktion sind
    {
      char a[100];
    } 
    
    void f2 (void)  // braucht mindestens 100 bytes solange wir in der funktion sind
    {
      char a[100];
      f1();        // jetzt sind es 200 (100 eigene und 100 aus f1)
      ...          // ab hier wieder nur 100
    } 
    
    void f3 (void)  // 0 bytes
    {
      f1();    // mal eben 100 bytes
      ...      // wieder 0
      f2();    // mal eben 200 bytes
      ...      // wieder 0
    }
    

    🙂


Anmelden zum Antworten