Rekursion erste Gehversuche versch. Varianten


  • Mod

    Nein, die andere Erklärung war richtig. work++ gibt dir den aktuellen Wert von work, erhöht work danach um 1. Das work dabei ein Zeiger ist, ändert auch nicht wirklich was. Der zeigt dann eben hinterher auf das nächste Element des Zeigertyps.



  • *work='x';
    work++;
    *work='y';

    ... puts(work) => xy

    So wird ein Schuh draus würd ich sagen. Hab ich etwas doof geschrieben gehabt.
    Also die andere Erklärung war "generell" gemeint,

    Zitat:
    work++ => Zeiger auf nächstes Element vom Typ auf den work zeigt?? Hope so...??

    ... War "zur weiteren Verwendung"

    So stimmts doch, hätt ich gesagt?


  • Mod

    beginner88888 schrieb:

    *work='x';
    work++;
    *work='y';

    ... puts(work) => xy

    Korrekt. Wobei du, wenn du es so schreibst, den ganzen Vorteil des Postinkrements verschenkst. Der Code ist schließlich identisch zu

    *work='x'; 
    ++work;
    *work='y';
    

    oder

    *work='x'; 
    work += 1;
    *work='y';
    

    oder ähnliches.

    Die spezielle Eigenschaft, dass das Postinkrement den ursprünglichen Wert zurück liefert, kannst du so nutzen:

    *work++='x'; 
    *work='y';
    


  • So, nun géhts weiter mit **char bzw. 2 Dim Array. Ich weiß es ist nicht dasselbe.
    Vorab:
    1.) Ich hab mich nicht eingelesen, ich hab´s jetzt mal so probiert wie ich es mir erdacht habe, möglich das es total falsch ist( obwohl es funktioniert)
    2.) Übung, bzw. Experimental, das hier **char unnötig ist, da ich ja ein statisches 2 Dim Array machen könnte da ja ZEILEN und LEN fest ist. Aber darum geht´s ja nicht.

    => Erklärungen, bzw. Fragen im Code als Kommentar, bin gespannt.

    Variante 1:

    Arbeitet mit Index, ich bin mir ziemlich sicher das es so stimmt
    dsi.c:

    #include <stdio.h>
    #include <stdlib.h>
    #define ZEILEN 3
    #define LEN 100
    
    void dsi(void){
    
    char **feld;    // Feld ist ein Zeiger auf einen Zeiger, der auf char zeigt
    int i, j;
    
    feld=malloc(ZEILEN*sizeof(*feld));  //feld bekommt von Malloc speicher für 3(Zeilen) x Zeiger auf char  => char *feld[3]??
    
    if (!feld){
               puts("Error Mallocation");
               exit(1);
        }     
    
    for (i=0; i<ZEILEN; i++){
              printf("Input[%d]:", i);
              feld[i]=malloc(LEN);     // Hier Speicher für den Zeiger[i] anfordern
              fgets(feld[i], LEN, stdin);
              } 
    
    puts("Now let´s see the Inputs...");
    
    for (j=0; j<ZEILEN; j++){
           printf("Input[%d] was:\n", j);
           puts(feld[j]);
           }
    
    free(feld);  //wird auch der Speicher von fled[i]=malloc(LEN) hier frei oder??
    
    }//END
    

    Variante 2 ist mein "Sorgenkind". Auch sie funktioniert so weit ich es getestet habe, jedoch ist die derefferenzierung mit ** etwas haarig 🙂
    Die Überlegung im Code ist hoffentlich verständlich, noch besser wäre wenn sie Richtig ist.

    dsp.c

    #include <stdio.h>
    #include <stdlib.h>
    #define ZEILEN 3
    #define LEN 100
    
    void dsp(void){
    
    char **feld, **start;
    int i, j;
    
    feld=malloc(ZEILEN*sizeof(*feld));  // Feld ist ein Zeiger auf einen Zeiger, der auf char zeigt
    
    if (!feld){
           puts("Error Malloc");
           exit(1);
        }
    
    start=feld;      //start für spätere Anzeige "setzen"
    
    /* Für die Pointer hab ich mir folgenden Zusammenhang erdacht: 
       value <= *pointer  <= ** pointer
                                pointer++ erhöht *pointer , also bei mir  : erhöhung der 3 Feld Zeiger
              (*pointer)++    => wenn value ein String wäre, Zeiger zeigt auf nächsten Buchstaben?
           (**pointer)++     => erhöht value */
    
    for (i=0; i<ZEILEN; i++){
           printf("Eingabe[%d]: ", i);
           *feld=malloc(LEN);    // Dereferenziert : 1.ZEiger auf Char Speicherplatz  zuweisen
           fgets(*feld, LEN, stdin);
           feld++;               // Feldzeiger erhöhen, feld[0] auf feld[1] quasi
           }
    
    puts("Lets see again...\n");
    
    for (j=0; j<ZEILEN; j++){
            printf("Input[%d] was:\n", j+1);  
            puts(*start);
            start++;
       }
    
    free(feld);  //reicht das?
    
    }//END
    

    Stimmt das mit den Pointern so ?


  • Mod

    Erstes Programm:

    free(feld);  //wird auch der Speicher von fled[i]=malloc(LEN) hier frei oder??
    

    Nein, wird nicht wieder frei. Muss vorher noch explizit freigegeben werden, ansonsten Speicherloch.

    Zweites Programm:
    Wieder falsch, sollte beim Ausführen Abstürzen. Wieder die gleichen Fehler wie in diesem Thread:
    http://www.c-plusplus.net/forum/323104
    Ich wiederhole mal nicht, was dort gesagt wurde.



  • Stürzt nicht ab bei mir, darum hab ich mir auch nicht weiter Gedanken gemacht.

    Würde es reichen, wenn ich

    feld=malloc(ZEILEN*sizeof(*feld));

    char **arbeit =feld;

    und dann mit "arbeit" weitermache? alsoo statt feld++ arbeit++ ??
    Nicht oder, in der 1. For schleife erhalte ich ja wieder Speicher von Malloc, den ich nicht "verbiegen" darf....
    Wie gesagt, bei der Index Variante war ich mir fast sicher das es passt, ich würde es aber trotzdem gerne mit Pointern lösen. Sch*dr**.

    Stimmt wenigstens das wie ich es mir mit den Pointern gedacht habe?
    Also erst Speicher für 3 Zeiger und dann jeden Zeiger speicher zuweisen?


  • Mod

    beginner_offl schrieb:

    Stimmt wenigstens das wie ich es mir mit den Pointern gedacht habe?
    Also erst Speicher für 3 Zeiger und dann jeden Zeiger speicher zuweisen?

    Das ist an sich die richtige Vorgehensweise, wenn man eine (zur Compilezeit) unbekannte Anzahl von Zeichenketten mit jeweils unterschiedlicher, unbekannter Länge möchte. Hier ist das natürlich doppelt umständlich, da sowohl die Länge aller Zeilen gleich ist. Das heißt, du könntest direkt Zeilenzahl*Zeilenlänge reservieren, anstatt Zeilenzahl Male einzeln eine einzelne Zeilenlänge zu reservieren. Da die Zeilenzahl zudem zur Compilezeit bekannt ist, kannst du dir auch gleich malloc sparen und ein statisches Array char daten[zeilenzahl][zeilenlänge] benutzen.
    Ignorieren wir das mal und nehmen an, dass du einfach aus Prinzip malloc benutzen möchtest und dass du die Indexschreibweise meiden möchtest. Dann bieten sich zwei Ideen an:
    -Du machst es richtig sauber und trennst die Verantwortlichkeiten. Funktionen die sich um Speicher kümmern, Funktionen die auf diesem Speicher arbeiten.
    -Du korrigierst deine Version. Das könnte so aussehen:

    void dsp(void){
    
      char **feld, **iterator;
      int i;
    
      feld=malloc(ZEILEN*sizeof(*feld));  
    
      if (!feld){
        puts("Error Malloc");
        exit(1);
      }
    
      iterator = feld;
    
      for (i=0; i<ZEILEN; i++){
        printf("Eingabe[%d]: ", i);
        *iterator=malloc(LEN);  
        fgets(*iterator, LEN, stdin);
        iterator++;    
      }
    
      puts("Lets see again...\n");
      iterator = feld; 
    
      for (i=0; i<ZEILEN; i++){
        printf("Input[%d] was:\n", i+1);  
        puts(*iterator);
        iterator++;
      }
    
      iterator = feld; 
      for (i=0; i<ZEILEN; i++){
        free(*iterator);
        iterator++;
      }
    
      free(feld);  
    }
    

    Du siehst, das ist nicht sehr verschieden von dem, was du hattest, aber ich habe aufgepasst, dass der ursprüngliche Zeiger auf das Feld nicht verloren geht und habe zum Arbeiten immer eine Arbeitskopie (den iterator) benutzt.

    Hier sind sehr oft noch Codes wie

    for (...)
    {
      tu_was(*iterator);
      iterator++;
    };
    

    drin. Wie ich dir im anderen Thread schon erklärt habe, lässt sich das auch kompakter schreiben als:

    for (...)
    {
      tu_was(*iterator++);
    };
    


  • Ignorieren wir das mal und nehmen an, dass du einfach aus Prinzip malloc benutzen möchtest und dass du die Indexschreibweise meiden möchtest

    Ja, das war Sinn und Zweck der Übung. Index = bäh 😉
    Spass beiseite, Zeilen und Spalten länge sind mir ja bekannt, aber ich wollte mal das "Grundprizip" wie ich aus **char ein 2Dim Array machen kann (ist so nicht ganz richtig, ich weiß) erarbeiten.

    Du siehst, das ist nicht sehr verschieden von dem, was du hattest, aber ich habe aufgepasst, dass der ursprüngliche Zeiger auf das Feld nicht verloren geht und habe zum Arbeiten immer eine Arbeitskopie (den iterator) benutzt

    Das habe ich mit

    Würde es reichen, wenn ich

    feld=malloc(ZEILEN*sizeof(*feld));

    char **arbeit =feld;

    und dann mit "arbeit" weitermache? alsoo statt feld++ arbeit++ ??

    gemeint. Cool, ich lag gar nicht so falsch. Jipieio!!

    =>Malloc wie Realloc, ich darf den "Original-Zeiger" den ich von Mall bzw. Reall erhalte einfach nicht anfassen und schon bin ich save...

    Das mit dem Speicher wiede freigeben, habe ich in den Minuten vor deinem Post gemacht. (Klar das kann jetzt jeder schreiben, ist aber so 🙂 ).

    So, jetzt noch was anderes.... Index Schreibweise , ja oder nein? Wie sieht´s aus in der Praxis? Geschmackssache oder nicht?

    =>Und noch wichtiger: Wie gesagt, bei mir ist es nicht abgestürzt, weder mit DevC++ noch mit CodeBlocks.... Bei DevC++ find ich auch nicht´s um die Compilerwarnstufen hochzusetzten, aber davon abgesehe... Der Compiler würde da auch nicht meckern schätz ich. .... Wie prüf ich solche Fälle am besten? (Klar durch "es Besser wissen" wird einfacher...)



  • Nachtrag : Die "Erklärung" für die Dereffernzierungen passen soweit ja?



  • Überarbeitet Version:

    #include <stdio.h>
    #include <stdlib.h>
    #define ZEILEN 3
    #define LEN 100
    
    void dsp(void){
    
    char **feld, **work;
    int i, j, dummy;
    
    feld=malloc(ZEILEN*sizeof(*feld));   
    
    if (!feld){
           puts("Error Malloc");
           exit(1);
        }
    
    work=feld; 
    
    for (i=0; i<ZEILEN; i++){
           printf("Eingabe[%d]: ", i+1);
           *work=malloc(LEN);       
           if (!work){
                      puts("Error Malloc");
                      exit(1);
               }            
           fgets(*(work++), LEN, stdin);       
        }
    
    puts("Lets see again...\n");
    
    work=feld;
    
    for (j=0; j<ZEILEN; j++){
            printf("Input[%d] was:\n", j+1);  
            puts(*(work++));
    
       }
    
    //Free Lines
    for (dummy=0; dummy < ZEILEN; dummy++){
          free(*(feld++)) ;
        }
    
    free(feld);   
    
    }//END
    

  • Mod

    beginner_offl schrieb:

    So, jetzt noch was anderes.... Index Schreibweise , ja oder nein? Wie sieht´s aus in der Praxis? Geschmackssache oder nicht?

    Du nimmst das, was du brauchst. Wenn du von vorne bis hinten iterierst, ist eine Indexvariante eher unnötiger Aufwand, die ist dazu da, dass man wahlfrei zugreifen kann, wo es gerade nötig ist. Daher ist sie (wenn sie nicht wegoptimiert wird) ganz miniml langsamer, was manchmal wichtig sein kann. Dafür finde ich die Schreibweise leserlicher, was wieder an anderen Stellen wichtig sein kann.

    =>Und noch wichtiger: Wie gesagt, bei mir ist es nicht abgestürzt, weder mit DevC++ noch mit CodeBlocks.... Bei DevC++ find ich auch nicht´s um die Compilerwarnstufen hochzusetzten, aber davon abgesehe... Der Compiler würde da auch nicht meckern schätz ich. .... Wie prüf ich solche Fälle am besten? (Klar durch "es Besser wissen" wird einfacher...)

    Das sind Laufzeitfehler, da kann der Compiler nichts mehr machen. Also ich habe es dadurch gemerkt, dass bei meiner Implementierung (von malloc/free) ein fetter Fehler vonwegen ungültigem free kam. Wenn das deine Implementierung nicht macht, ist das ein bisschen ungünstig, dann musst du dich eben über andere Debugmethoden deiner Plattform kundig machen. Weiterhin ist auf meiner Plattform auch das schöne Progrämmchen valgrind verfügbar, mit dem man sehr viele Fehler dieser automatisch Art findet, selbst gut versteckte. Wieder dürfte dies bei dir nicht gehen und daher musst du dir selbstständig passende Werkzeuge suchen (oder mal im passenden Forum fragen, was andere empfehlen).

    beginner_offl schrieb:

    Nachtrag : Die "Erklärung" für die Dereffernzierungen passen soweit ja?

    Welchen Beitrag genau meinst du? Der Thread ist ziemlich lang geworden 🙂



  • Weiterhin ist auf meiner Plattform auch das schöne Progrämmchen valgrind verfügbar
    

    Wenn man fragen darf, was benutzt du?

    Code im Nachtrag passt jetzt so , ja?

    Welchen Beitrag genau meinst du? Der Thread ist ziemlich lang geworden

    /* Für die Pointer hab ich mir folgenden Zusammenhang erdacht: 
       value <= *pointer  <= ** pointer
                                pointer++ erhöht *pointer , also bei mir  : erhöhung der 3 Feld Zeiger
              (*pointer)++    => wenn value ein String wäre, Zeiger zeigt auf nächsten Buchstaben?
           (**pointer)++     => erhöht value */
    

  • Mod

    beginner_offl schrieb:

    Wenn man fragen darf, was benutzt du?

    Diese geheimnisvolle Hackersystem, von dem immer alle reden. Linux oder so ähnlich heißt das.

    Code im Nachtrag passt jetzt so , ja?

    Sieht vom Lesen her korrekt aus.

    Hier sieht man auch schön das Speicherloch, dass du erzeugst, wenn du in Zeile 26 abbrichst. Weil dann ja nie ein free erfolgt. Aber das in C vollkommen korrekt umsetzen zu wollen, das ist der Grund, warum man höhere Sprachen erfunden hat, die das automatisch machen. Das darfst du bloß mal im Hinterkopf behalten, als etwas was so nicht 100% korrekt ist, aber mach dich darum nicht verrückt.

    Welchen Beitrag genau meinst du? Der Thread ist ziemlich lang geworden

    /* Für die Pointer hab ich mir folgenden Zusammenhang erdacht: 
       value <= *pointer  <= ** pointer
                                pointer++ erhöht *pointer , also bei mir  : erhöhung der 3 Feld Zeiger
              (*pointer)++    => wenn value ein String wäre, Zeiger zeigt auf nächsten Buchstaben?
           (**pointer)++     => erhöht value */
    

    Korrekt außer

    pointer++ erhöht *pointer

    pointer++ erhöht pointer.



  • Ok danke.
    Privat hab ich auch dieses ominöse Linux 😉 auf Arbeit aber Windows. Das wird wohl auch so bleiben :|

    Wenn ich noch eine Frage frei habe:
    Jetzt wo malloc und realloc so weit klar ist, will ich mal meinen ersten c Versuch , zeilenweises einlesen von Strings wida aufnehmen. Auch wenn es wohl mit Elefanten auf Spatzen schießen ist, probierm will ichs.
    Aber mir ist nicht klar wie ich sinnvoll zurückgebe.
    Hab noch keinen Code, aber will quasi char Weise einlesen bis ZeilenEnde und dabei Speicher erweitern. Nur wie geb ich zurück? Als Zeiger? Dann musste ich beim Aufruf schon Speicher bereitstellen. Nicht der Hit. In nen char buffer? Könnte zu klein sein. Die Funktion soll ja erleichtern....
    Hoffe das war verständlich. Muss am Handy tippen weil ich gerade für Monika gruber Karten anstehe in der Kälte 🙂



  • =>=> Mir ist jetzt noch was wichtiges eingefallen, was mir sehr am Herzen liegen würde, weil ich darauf auch in dem Realloc Thread nicht wirklich gekommen bin:

    Zitat:
    Ignorieren wir das mal und nehmen an, dass du einfach aus Prinzip malloc benutzen möchtest und dass du die Indexschreibweise meiden möchtest

    Jep, das möchte ich immer noch, bin mir aber nicht sicher wie sich das im folgenden Fall verhält / ich lösen könnte (Hab keine Code, ist nur eine Überlegung):

    iterator = feld;
    
      for (i=0; i<ZEILEN; i++){
        printf("Eingabe[%d]: ", i);
        fgets(*iterator, LEN, stdin);
         if(mehr_speicher_bedingung){
        //angenoommen ich habe für iterator schon ge-malloct, brauch jetzt aber doch mehr speicher : 
       *iterator=realloc(was_neues);    //  überprüfung mit evtl. tmp=realloc usw usw
      // => dann ist iterator mein "originalzeiger" 
           }
        iterator++  //=> Dann hab ich doch hier ein Problem, Rückgegebener Zeiger von Realloc / Malloc in Ruhe lassen....
    

    =>Müsste ich dann mit noch einem Hilfszeiger arbeiten? Aber wo weise ich den so sinvoll zu, das er weiterhin nach "jedem" Realloc noch passt?

    Also wenn quasi unter Umständen zum 4. mal Realloc kommt(fügt ja den neuen Speicher hinten an...), sollte mein Zeiger auf den nächsten "freien" Platz zeigen....

    Ich komm nur auf ne Index Lösung, aber das MUSS auch anders gehen.
    =>"index" wegspeichern mit pointerende-pointeranfang und dann später iterator+=weggespeichererter_index?? Is doch Käse oder??
    Ich hoffe das war verständlich, blick grad selber nicht mehr durch 😕 😕

    Also wer mir das verständlich rüberbringt, hat echt was gut.


  • Mod

    Du kannst Pointerarithmetik benutzen. Vor dem realloc kannst du dir damit ausrechnen, wie groß der Offset des Laufzeigers relativ zum Beginn ist, nach dem realloc rechnest du auf den neuen Beginn den Offset drauf und hast dann wieder einen passenden Laufzeiger.

    Bezüglich sauberer Eigenimplementierung eines dynamischen gets: Das sauberste wäre es wohl sich hier die ganze Speicherverwaltung zu kapseln. Ein struct mit den wichtigsten Daten (Anfang des reservierten Bereichs, Ende des reservierten Bereichs, Ende des belegten Bereichs) und eine Art "Konstruktor" und "Destruktor" (falls du diese Begriffe von anderen Sprachen kennt) und weitere Funktionen zum Zugriff, ganz nach Bedarf.
    Ist viel Aufwand.



  • Ok, danke. Das dynamische "gets" ist eigentlich dann für meine pillepalle Programme den Aufwand nicht wert. Aber vielleicht wenn mal viel Zeit ist.

    Du kannst Pointerarithmetik benutzen. Vor dem realloc kannst du dir damit ausrechnen, wie groß der Offset des Laufzeigers relativ zum Beginn ist, nach dem realloc rechnest du auf den neuen Beginn den Offset drauf und hast dann wieder einen passenden Laufzeiger.

    => würde das so passen?:
    (Beispiel ist ziemlich beschränkt, das geb ich zu...)

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define BRK 3
    #define END 30
    
    void re_int_ptr(void){
    
    int *feld, *iterator, run, index, value ;
    
    feld=malloc(sizeof(*feld)*BRK);  
    if (!feld){ puts("Error Mallocation"); exit(1);}
    iterator=feld   ;  
    
    for (run=0; run < END; run++){
                printf("Input for Feld[%d]:", run);
                scanf(" %d", &value);
                *iterator=value;
                index=iterator-feld;
                        if (run+1 < BRK)  {
                                  puts("Stored in Malloced Memory");
                                  }
                                  else if (run+1 ==BRK) {
                                           puts("Realloc Needed");
                                           feld=realloc(feld, (sizeof(*feld)*END));
                                           if(!feld){puts("Error Realloc!!"); exit(1);}
                                           iterator=feld;
                                           iterator+=index;
                                       }
                iterator++;
    
          }                                        
    
    int j; 
    iterator=feld;
    for (j=0; j<END; j++){
        printf("Feld[%d]: %d\n", j, *iterator++); 
    }           
    
    free(feld);     
    
    }//END
    

    =>Index=iterator-feld... müsste so passen, ja?

    =>feld = malloc (3) oder feld = malloc(sizeof(int) *3 ??
    Laut Referenz ist für Malloc und Realloc je größe in Bytes.... => feld =malloc(3) wäre bei nem char feld richtig, bei Int falsch. !?

    Wenn ich speicher nicht freigebe mit free.... kann es sein das mein Windows dann keinen Speicher mehr hergibt? Habe beim Tippen nämlich das free aus versehen mal mitgelöscht. Nach zirka 10 mal "Testen" war realloc immer NULL, also ich bekam immer meine Fehlermeldung "Error Realloc". Habe dann Win neu gestartet und es ging wieder.


  • Mod

    Das Programm ist technisch korrekt. Aber es ist irgendwie total verwirrt. Was ist denn der Unterschied zwischen deiner Variablen run und einem Index? Du hast doch jetzt nur den Namen geändert, dafür aber nochmal eine unnötige (denn index == run) Extra-Indexberechnung rein gemacht (die auch eigentlich in den Block bei Zeile 27 gehört).

    Wenn ich speicher nicht freigebe mit free.... kann es sein das mein Windows dann keinen Speicher mehr hergibt? Habe beim Tippen nämlich das free aus versehen mal mitgelöscht. Nach zirka 10 mal "Testen" war realloc immer NULL, also ich bekam immer meine Fehlermeldung "Error Realloc". Habe dann Win neu gestartet und es ging wieder.

    Nein, außer du hast einen Rechner und Betriebssystem von 1965. Du hast bei deinen Experimenten irgendeinen anderen Fehler eingebaut.

    Laut Referenz ist für Malloc und Realloc je größe in Bytes.... => feld =malloc(3) wäre bei nem char feld richtig, bei Int falsch. !?

    So ist es.



  • Das Programm ist technisch korrekt.

    Das freut mich doch sehr, vor allem der block ab Zeile 27 war mir wichtig mit dem "berechneten" Index... Der wie du schon geschrieben hast, natürlich nicht nötig wäre, da run==index..... Tja was soll ich sagen...

    Aber es ist irgendwie total verwirrt

    => schon 🙂

    Nein, außer du hast einen Rechner und Betriebssystem von 1965. Du hast bei deinen Experimenten irgendeinen anderen Fehler eingebaut.

    hm... seltsam, naja, wird dann wohl so sein. Also wenn meine Speicheranforderungen kein free erhalten UND mein Programm nicht abstürzt, dann ist nach Programm-Ende wida alles Paletti? Windoof ist das auch egal? hmm


  • Mod

    beginner_offl schrieb:

    hm... seltsam, naja, wird dann wohl so sein. Also wenn meine Speicheranforderungen kein free erhalten UND mein Programm nicht abstürzt, dann ist nach Programm-Ende wida alles Paletti? Windoof ist das auch egal? hmm

    Ja, jedes Betriebssystem, dem du jemals begegnen wirst, holt sich nach Programmende seine Ressourcen zurück, egal wie das Programm beendet wurde. Sonst wären Computer ziemlich unbenutzbar.
    Dies gilt vielleicht nicht mehr, wenn du mal für einen Microcontroller programmierst, also schön aufpassen und gleich richtig angewöhnen.
    Es gilt ebenfalls nicht für Ressourcen, die gar nicht vom Betriebssystem verwaltet werden. Wenn dein Programm z.B. irgendwelche Kommunikationsverbindungen aufmacht und diese nicht sauber beendet, dann bleiben die auch nach Programmende bestehen, weil das Betriebssystem gar nicht weiß, was solch eine Verbindung ist. Da die Techniken, wie man Ressourcen sauber reserviert und wieder frei gibt ziemlich genau die gleichen sind, egal um welche Art von Ressource es sich handelt, ist es eine gute Idee, es bei allen Arten von Ressourcen gleich richtig zu machen, damit man es sich angewöhnt. Gerade bei dynamischem Speicher hast du recht leicht die Möglichkeit, Fehler zu entdecken, und du kannst beim Experimentieren auch nichts kaputt machen. Da dran kann man also gut üben.


Anmelden zum Antworten