Array -> dynamisch Groesse ?



  • TheTester schrieb:

    ich wär ja fies wenn ich sagen würde, lies ein C buch
    guck mal nach malloc() und realloc() das wären zb. anlaufstellen...

    bye

    tt

    Ich habe ein buch vor mir liegen, aber ich versteh das nicht mit malloc und realloc.

    Sonst wuerde ich nicht fragen.



  • Was genau verstehst du bei malloc() und realloc() nicht? Verstehst du möglicherweise noch nicht wie Zeiger funktionieren?



  • AJ schrieb:

    Was genau verstehst du bei malloc() und realloc() nicht? Verstehst du möglicherweise noch nicht wie Zeiger funktionieren?

    OK, Beispiel.

    /* Wir reservieren Speicherplatz fuer unsere Struktur fuer das erste 
       Element der Liste*/
      if((anfang =(struct punkt *)
      malloc(sizeof(struct punkt))) == NULL)
      fprintf(stderr,"Kein Speicherplatz vorhanden fuer anfang\n");
    

    Ich habe in meinen Programm zwei Sturkturen.
    Und damit wird das Speicher freigegeben fuer den Hinhalt, der da rein kommt.

    Aber ich versteh den Syntax nicht.

    sizeof ist klar und malloc auch, aber wohin worauf beziehen die sich?

    Und wie muss ich dann das ARRAY vergroessern ?? Das ist zu hoch fuer mich.



  • Ach so. Und ein Zeiger zeigt auf eine Adresse im Speicher und in dem Teil des Speichers steht dann z.B. der Wert oder eine weitere Adresse, der zu dem Wert zeigt, der vergeben ist.

    RICHTIG ?



  • Gut, das mit den Zeigern scheinst du schon mal verstanden zu haben :).

    Also malloc() reserviert dir Speicher. Ich denke das hast du auch schon verstanden, oder? Damit malloc() nun weiß wieviel Byte reserviert werden müssen, machst du die sizeof()-Angabe. Es wird also in deinem Beispiel ein Speicherplatz reserviert, der die Größe deines structs hat. Das was malloc() zurückliefert ist der Zeiger auf die Anfangsadresse des reservierten Speichers. Verstanden?

    Wenn du nun ein "Array" deiner Struktur haben willst, dann musst du natürlich malloc() sagen, dass es auch genug Speicher für dein "Array" reserviert. Du musst also den Wert von sizeof() mit der Anzahl der "Array"-Elemente multiplizieren.

    Die Funktion realloc() brauchst du, um den reservierten Speicher zu erweitern oder zu verkürzen und dabei den Inhalt zu behalten. Darum musst du realloc() auch als erstes den Zeiger übergeben des bisher reservierten Speichers. Eventuell gibt realloc() eine andere Adresse zurück, deswegen musst du den Rückgabewert wieder auf deinen Zeiger schreiben.

    Beispiel:

    ...
    int i;
    int *zahlen;
    unsigned int anzzahlen=1, eingabe;
    
    zahlen = malloc(sizeof(int)*anzzahlen); //reserviere Speicher für 1 Zahl
    
    zahlen[0] = 1234;
    
    printf("1. Zahl: %d\n\nWieviele Zahlen sollen zusäztlich eingegeben werden? ", zahlen[0]);
    scanf("%ud", &eingabe);
    anzzahlen += eingabe;
    
    zahlen = realloc(zahlen, sizeof(int)*anzzahlen);
    ...
    

    Falls du noch Fragen hast, frag einfach ;).



  • Ok,

    Vielen dank.

    Das war seid langen mal eine sehr gute beschreibung und ich denke, nun weiss ich, wie man das programmiert und werde das gleich mal testen.
    Das scheind gar nicht so schwer zu sein, wenn man es erstmal verstanden hat.

    Aber eine Frage hab ich dennoch, wenn ich keine Zahl, sondern "ein Char" ( Zeichen ) habe, wieviel muss ich dann frei geben ?

    Nur fuer eins ist wichtig, denn eine multiplikation kann ich dann leicht machen.



  • Ein char hat normalerweise die Größe eines Bytes, d. h. du brauchst da eigentlich gar nichts multiplizieren. Die Anzahl der benötigten chars reicht also schon. Du kannst natürlich vorsichtshalber immer sizeof(datentyp) verwenden. Bei char würde sizeof() hald 1 zurückliefern.



  • AJ schrieb:

    Ein char hat normalerweise die Größe eines Bytes, d. h. du brauchst da eigentlich gar nichts multiplizieren.

    «normalerweise»? Immer. Ein Byte ist definiert als der Speicherplatz den ein char belegt. Sollte das einmal mehr als 8 Bits sein (kommt vor), dann ist eben ein «Byte» auch größer als 8 Bits.
    Der Begriff Byte ist im Zusammenhang mit dem C-Standard also etwas anderes als im Sprachgebrauch der restlichen Welt.



  • @Bashar
    Danke für die Aufklärung 🙂



  • OK, das geht jetzt, aber ich machen immernoch einen Fehler, den ich nicht verstehen.

    Ich habe

    int len=0;
    char *buf,*test;
    char *hallo="2.3,3.4,4.5,6=LAYER-HOEHE";
    buf=malloc(sizeof(hallo));
    while(hallo[len])
    {
     buf[len]=hallo[len];
     len++;
    }
    len=0;
    test=malloc(sizeof(buf));
     /* da ist ein fehler, denn das BUF wird mit einem Zeichen ueberschrieben und dann steht da drin buf="2.3,3.4,4.5-6.6-LAYER-HOEHE  */
    while(buf[len])
    {
     test[len]=buf[len];
     len++;
    }
    /* und dann wird das falsche uebertragen.   */
    

    Warum wird das ueberschrieben ?? Ich brauche aber den richtigen wert.

    der wert BUF wird ueberschrieben, wenn ich den Speicher fuer TEST frei gebe.



  • Es gib verschiedene Dinge!
    1. Kann ich den Zweck dieses Programms nicht erkennen! (oder evtl. eine Übung?)

    2. beim vergeben des speichers an den Pointer "buf" vergibst du gerade mal, wenn es gut kommt ca 4 bytes an den Pointer!! Die String länge, Länge eines char Arrays (und in deinem Fall, sogar pointer auf pointer(==Array)) lässt sich nicht mit sizeof() herausfinden!! (fkt. strlen() liefert Stringlenge ohne "NULL Terminierung").
    Angenommen, du Gibst mit mit "malloc()" 4 bytes frei, bedeutet das für einen char*, eine Arraygrösse von 4 Zeichen(==char buf[4];)! und dann ist fertig! alles was du darüber hinausschreibst kann Verfälschungen in z.B. Rücksprungadressen geben (es soll leute geben, die so was ausnützen!!) 😉

    d.h.

    buf=malloc(sizeof(hallo)); 
    while(hallo[len]) 
    { 
     buf[len]=hallo[len]; 
     len++; 
    }
    

    führt zwangsläufig zu einem Buffer Overflow!

    zu deinerFrage: An dem "Überschreiben", bist du selbst schuld!? den mit der (weiter oben gelisteteten)while schlaufe, kopierst du Wert für Wert von "hallo" nach "buf"!!!
    Fehler? oder seh ich das falsch!?

    gruss

    Irrtümer vorbehalten 🙂



  • Ich wollte das Prinzip verstehen. Denn ich lese eine datei zeileneweise aus, und das steht in einem Zeiger. Und dies wollte ich auch einen anderen Zeiger kopieren. Ich hatte es frueher in einem Feld, aber wenn die Zeile zu lang wird, kann ich die Feldgroesse nicht aendern. Ich weiss jedenfalls nicht, ob das geht.

    Wie kann ich den Fehler richtig stellen. Ich brauche den Wert von den einen Zeiger nun mal auf den anderen auch.denn der erste zeiger wird neu ueberschrieben.



  • Chris233 schrieb:

    Ich wollte das Prinzip verstehen. Denn ich lese eine datei zeileneweise aus, und das steht in einem Zeiger. Und dies wollte ich auch einen anderen Zeiger kopieren. Ich hatte es frueher in einem Feld, aber wenn die Zeile zu lang wird, kann ich die Feldgroesse nicht aendern. Ich weiss jedenfalls nicht, ob das geht.

    Wie kann ich den Fehler richtig stellen. Ich brauche den Wert von den einen Zeiger nun mal auf den anderen auch.denn der erste zeiger wird neu ueberschrieben.

    OK, Problem ist erledigt mit

    -> strlen


Anmelden zum Antworten