Hallo Ich lese gerade ein Buch ueber dynamische Speicher malloc(). Ich habe alle wichtigen Dateien angehaengt. Mich interessiert lediglich das mit dem strdup(). Ich habe einen struct insel. Dann 2 Funktionen anzeigen und erstellen. Auf dem vorletzten Bild sieht man wie 2 Inseln erzeugt werden, sprich 2 pointer. Was ich nicht verstehe ist, warum ich den Namen damit ueberschreibe und anstatt den Namen des Array strings die strdup() funktion nutzen muss. Ich mache mit der Zuweisung des Namens mittels name eine call by refence. Also handelt es sich nicht um eine Kopie. Aber warum wird der Name eigentlich ueberschrieben? Denn ich erstelle doch 2 verschiedene Pointer, die jeweils auf 2 verschiedene Pointer/Adressen zeigen, die von der malloc zurueckgegeben wird. Oder gibt mir malloc jedes mal einen Pointer zurueck der auf die gleiche Adresse zeigt? Wenn die Adresse von p-insel0 4.000.000 ist und die von p-insel1 4.500.000 ist frage ich mich warum i->name auf die selbe adresse zeigen. Bitte um Hilfe
Du musst dich an diesem Punkt mit dem Unterschied zwischen "Deep Copy" und "Shallow Copy" auseinandersetzen, siehe: https://stackoverflow.com/a/37830340 Im 3. Bild machst du eine "Shallow Copy", das heißt der Name existiert nur einmal im Speicher, du hast zwei Pointer auf den gleichen String. Im 5. Bild ist es dann eine "Deep Copy", das heißt der Name existiert zweimal im Speicher, du hast zwei unterschiedliche Pointer auf zwei unterschiedliche Strings.
strdup() kopiert den string und gibt den pointer auf diese Kopie zurück. Dabei passiert genau das selbe mit malloc().. Das wurde schon korrekt erklärt. Das gefährliche daran ist dann zu vergessen den speicher dieser Kopie wieder frei zu geben. Um das zu vermeiden legt man den Länge des Strings "name" fest z.bsp auf 64 Zeichen name[64] in der Struktur.
Der Rückgabewert von malloc und strdup muss immer (!) auf != NULL geprüft werden! Wie heißt dieses unsinnige Buch?
Marco H. schrieb: > strdup() kopiert den string und gibt den pointer auf diese Kopie zurück. > Dabei passiert genau das selbe mit malloc().. Das wurde schon korrekt > erklärt. > > Das gefährliche daran ist dann zu vergessen den speicher dieser Kopie > wieder frei zu geben. Dafür ist das Gefährliche an der flachen Kopie, dass man den selben Speicher zweimal freizugeben versucht, wenn man nicht aufpasst.
Beitrag #5673365 wurde von einem Moderator gelöscht.
Beitrag #5673368 wurde von einem Moderator gelöscht.
Beitrag #5673534 wurde von einem Moderator gelöscht.
Hi Ich habe mir das Ganze nun aufgemalt. Die Pointer auf die erstellten Inseln auf dem Heap greifen so alle auf den selben String, der lokal auf dem Stack gespeichert ist. Wenn sich der Name lokal durch die Benutzereingabe mittels fgets() aendert, aendern sich alle Namen. Deshalb muss ich mittels strdup() Platz auf dem Heap schaffen und die aktuellen Namen dorthin kopieren. Danke trotzdem allen Helfenden
Ist ja klar.. Das sieht ja aus wie eine linked list. Die Strukturen werden alle hintereinander gehängt. C->B->A Dann hast du die Aufgabe nicht wirklich verstanden ;) Du kannst die Eingabe nicht mit einen Pointer aus dieser Liste machen :). 1. man macht sich Gedanken welche maximale länge der Name haben soll 2. nimmt für den name kein Pointer sondern ein String Array maximale Länge +1 3. fordert man speicher für die Struktur an 4. schiebt man die zeichen vom "Name" in das Array -> maximale Länge prüfen und füllt die Struktur mit Daten 5. hängt man die Struktur an die Liste an... Außerdem musst du dir Gedanken machen die Liste zu schützen (Thread safe).. Mit fgets() musst du ja schon wissen wie groß der String ist, oder du ließt Zeichenweise vom Stream. Die Daten landen in einen Buffer welchen du duplizierst und den Pointer in der Struktur anhängst. Deine Aussage oben deutet darauf das du den Buffer Pointer anhängst, nicht die Kopie... Wenn man das so macht wie oben muss man aufpassen name zuerst freizugeben, bevor man die Struktur frei gibt. Sonst greifst in einen ungültigen Bereich zu... Das doppelt buffern macht keinen Sinn, da jedes Element in deiner ja einen Namen haben soll kann man dafür ein ein String Array benutzen. Dann wird der Platz dafür mit der Struktur geschaffen und auch wieder freigegeben.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.