1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Lexikon
  • Erweiterte Suche
  1. Informatik Forum
  2. Webmaster & Internet
  3. Entwicklung

Pointers über Pointers ;-)

  • sommeralex
  • 21. Dezember 2005 um 23:29
  • Unerledigt
  • sommeralex
    11
    sommeralex
    Mitglied
    Punkte
    1.325
    Beiträge
    188
    • 21. Dezember 2005 um 23:29
    • #1

    Hallo!

    Ich muss gestehen, ich bin kein C Profi. Daher quält mich folgendes Problem:

    ich habe zwei Pointer Listen, welche mir "quasi" auf die selben Objekte x zeigen. eine "Mutterliste", sie zeigt direkt auf alle Objekte x. Und eine "Kindliste", sie zeigt nur auf einige Objekte meiner Mutterliste, doch sie zeigt nicht auf diese Objekte im eigentlichen sinne (direkt), sondern nur indirekt auf ein struct (und dieses struct zeigt direkt auf ein Objekt x).

    was passiert nun, wenn ich ein objekt von meiner Mutterliste gelöscht habe - wohin zeigt der Pointer meiner Kindliste, welche ursprünglich auf dieses Objekt gezeigt hat? Frage1. Frage2: muss ich diesen Pointer meiner Kindliste nicht auch über "free" loslösen? und wenn, versucht es dann auch, dass objekt x zu "löschen" (aus dem heap)

    hm.. vielleicht ist es auch nur spät..

    danke, alex

  • west
    6
    west
    Mitglied
    Punkte
    300
    Beiträge
    59
    • 21. Dezember 2005 um 23:38
    • #2

    ich habs so verstanden, bsp:
    speicher: 0123456789
    element der "mutterliste" zeigt auf 0
    element der "kindliste" auf 3

    afair:
    wenn du jetzt free(element "mutterliste") aufrufst, dann ist 0-9 weg.

    wenn du dann auf den bereich, auf den das element der "kindliste" zeigt, zugreifst, erhältst du eine speicherverletzung.

    mfg, west.

  • sommeralex
    11
    sommeralex
    Mitglied
    Punkte
    1.325
    Beiträge
    188
    • 21. Dezember 2005 um 23:56
    • #3

    struct x{

    }

    x *pointer_auf_x;

    struct y{

    x * pointer_auf_x;

    }

    y *pointer_auf_y;

    jetzt hab ich zwei listen, meine mutterliste aus einer einfach verketteten liste auf x. und eine kindliste, eine liste auf y.

    die frage ist, wenn ich jetzt ein element aus der mutterliste lösche, was passiert mit meiner liste aus y? oder umgekehrt: was passiert, wenn ich bsp. free(pointer_auf_y) mache? -> wird dann auch das objekt meiner mutterliste gelöscht?

  • Fup
    12
    Fup
    Mitglied
    Punkte
    1.460
    Beiträge
    291
    • 22. Dezember 2005 um 01:24
    • #4

    x *ptrX = new x();

    y *ptrY = new y();
    ptrY->ptrX = ptrX;

    delete ptrX;

    ab jetzt ist ptrY->ptrX undefiniert, d.h. bei Verwendung dessen kann es zu einer Speicherverletzung kommen, wie schon west erläutert hat. Der prtY->ptrX zeigt quasi irgendwohin. Wenn du ptrY->ptrX freigibst wird auch der Speicher von ptrX freigeben. Eine Freigabe könnte so aussehen:

    ptrY->ptrX = NULL;
    delete ptrX;
    ptrX = NULL;
    delete ptrY;
    ptrY = NULL;

    mfG Fup

  • sommeralex
    11
    sommeralex
    Mitglied
    Punkte
    1.325
    Beiträge
    188
    • 22. Dezember 2005 um 01:38
    • #5

    wenn ich


    free(head_alarm);

    if(head_alarm == NULL){

    printf("freed!\n");

    }

    mache, komme ich dennoch nicht in freed!.. warum?

  • west
    6
    west
    Mitglied
    Punkte
    300
    Beiträge
    59
    • 22. Dezember 2005 um 09:43
    • #6

    von c weiss ichs, von c++ nicht (wird aber vermutlich genauso sein):

    free() auf einen pointer gibt den dahinterliegenden speicher frei. free() lässt sich nur auf einen pointer anwenden, der von malloc(), calloc() oder realloc() zurückgegeben wurde. soweit so gut.
    der pointer selbst wird bei free() NICHT auf null gesetzt. (das geht bei c überhaupt nicht. -> Stichwort "call by value").
    free() hat auch keinen return value. afair: bei free() kann man von erfolgreicher durchführung ausgehen.

    (die "nice code"-konvention sagt, dass man nach einem free() den pointer auf null setzen soll. vorteil: wenn nochmal free() aufgerufen wird, passiert nichts.)

    > man 3 free

    Zitat

    DESCRIPTION
    free() frees the memory space pointed to by ptr, which must have been returned by a previous call to
    malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, unde-
    fined behaviour occurs. If ptr is NULL, no operation is performed.

    Zitat

    RETURN VALUE
    free() returns no value.

    mfg, west.

  • Fup
    12
    Fup
    Mitglied
    Punkte
    1.460
    Beiträge
    291
    • 22. Dezember 2005 um 11:46
    • #7
    Zitat von sommeralex

    wenn ich


    free(head_alarm);

    if(head_alarm == NULL){

    printf("freed!\n");

    }

    mache, komme ich dennoch nicht in freed!.. warum?

    Alles anzeigen

    Weil head_alarm nicht NULL ist. Wie schon erwähnt zeigt er irgendwo hin.

    mfG Fup

  • sommeralex
    11
    sommeralex
    Mitglied
    Punkte
    1.325
    Beiträge
    188
    • 22. Dezember 2005 um 13:14
    • #8
    Zitat von Fup

    Weil head_alarm nicht NULL ist. Wie schon erwähnt zeigt er irgendwo hin.



    vielen dank einmal für die antworten. es wundert mich nur, dass ich obwohl ich free(head_alarm) schreibe, "danach" immer noch auf head_alarm zugreifen kann!

  • west
    6
    west
    Mitglied
    Punkte
    300
    Beiträge
    59
    • 22. Dezember 2005 um 13:22
    • #9

    der pointer selber gehoert noch dir. der referenzierte bereich aber nicht mehr und kann dir vom OS jederzeit weggenommen werden, d.h. man produziert nicht in allen faellen eine speicherverletzung. (manche OS räumen erst auf, wenn der platz benötigt wird. manche sofort. voodoo.)

    mfg, west.

  • hal
    32
    hal
    Mitglied
    Reaktionen
    52
    Punkte
    11.122
    Beiträge
    2.208
    • 22. Dezember 2005 um 13:35
    • #10
    Zitat von sommeralex

    vielen dank einmal für die antworten. es wundert mich nur, dass ich obwohl ich free(head_alarm) schreibe, "danach" immer noch auf head_alarm zugreifen kann!

    Bei kleineren Allozierungen reserviert malloc meistens gleich einen größeren Block, und returnt aus diesem Block heraus Speicherplätze wenn noch mehr Platz ist drinnen. Dadurch wird der overhead kleiner gehalten.
    Dieses Verhalten ist allerdings nicht genauer spezifiziert, und man kann sich daher nicht drauf verlassen (weder zwischen OS, noch zwischen Computern, nichtmal zwischen Mondphasen am gleichen Computer).

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • sommeralex
    11
    sommeralex
    Mitglied
    Punkte
    1.325
    Beiträge
    188
    • 22. Dezember 2005 um 13:35
    • #11
    Zitat von west

    der pointer selber gehoert noch dir. der referenzierte bereich aber nicht mehr und kann dir vom OS jederzeit weggenommen werden, d.h. man produziert nicht in allen faellen eine speicherverletzung. (manche OS räumen erst auf, wenn der platz benötigt wird. manche sofort. voodoo.)



    danke - jetzt ist es klar! es wird qasi als "gelöscht markiert" ok. jetzt ist aber immer noch meine frage offen:

    wenn ein struct X auf andere structs Y zeigt, und ich dieses struct X mit free(struct X) anschreibe, werden dann auch meine structs Y "gelöscht"/free - obwohl noch andere zeiger auf diese zeigen?

    aber wie lösche ich nun "nur" die zeiger? (ohne die objekte zu löschen, auf die sie zeigen)

  • hal
    32
    hal
    Mitglied
    Reaktionen
    52
    Punkte
    11.122
    Beiträge
    2.208
    • 22. Dezember 2005 um 13:37
    • #12
    Zitat von sommeralex

    wenn ein struct X auf andere structs Y zeigt, und ich dieses struct X mit free(struct X) anschreibe, werden dann auch meine structs Y "gelöscht"/free - obwohl noch andere zeiger auf diese zeigen?

    Generell wird nichts gelöscht, was du ihm nicht sagst. Dir kanns auch passieren, dass du Speicher reserviert hast, auf den du keinen Pointer mehr hast, das ist dann ein memory leak.
    C und C++ haben per default keine garbage collection wie Java, Haskell und andere Sprachen!

    Am besten ist es, wenn du Pointer als normale Variablen ansiehst, die eine Speicheradresse als Inhalt haben (was ja auch wirklich der Fall ist). malloc() reserviert einen Block im Speicher und gibt die Anfangsadresse zurück. Irgendwann musst du genau diese Anfangsadresse wieder free() übergeben, dann wird der komplette Block wieder freigegeben. Mehr Magie passiert nicht (aus der Sicht des Programmierers).

    Zitat

    aber wie lösche ich nun "nur" die zeiger? (ohne die objekte zu löschen, auf die sie zeigen)

    meinzeiger = NULL;

    was äquivalent ist zu meinevariable = 0; bei Integer-Typen.

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • sommeralex
    11
    sommeralex
    Mitglied
    Punkte
    1.325
    Beiträge
    188
    • 22. Dezember 2005 um 13:45
    • #13

    also:

    ich habe eine liste, bestehend aus struct x, einfach verkettet. ich initialisiere diese zur laufzeit mit malloc - bis dahin ist mir alles klar.

    ich möchte nun zusätzlich noch eine liste, aus struct y (und struct y enthält struct x zeiger, diese zeigen alle auf die vorher schon erstellte liste bzw. objekte meiner liste)

    muss ich diese 2.liste über ein malloc initiieren? oder nicht? die zeiger, auf die dieses struct y liste zeigen, sind alle schon über ein malloc meiner 1.liste erzeugt worden, und daher persistent.

    wenn ich nun struct y "free" befehle, wirkt sich dass auch auf meine liste x aus? wenn ich die struct y liste über malloc initiiert habe, muss ich sie ja mit free loswerden. vielleicht muss ich aber gar nicht diese liste über ein malloc deklarieren, oder?

    ist ungefähr klar, worauf ich hinaus will?

  • sommeralex
    11
    sommeralex
    Mitglied
    Punkte
    1.325
    Beiträge
    188
    • 22. Dezember 2005 um 13:46
    • #14

    kann es vielleicht sein, dass ich nur den "speicher meines pointers" über free loswerden muss? also free(&pointer) ???

  • hal
    32
    hal
    Mitglied
    Reaktionen
    52
    Punkte
    11.122
    Beiträge
    2.208
    • 22. Dezember 2005 um 13:50
    • #15
    Zitat von sommeralex

    ich möchte nun zusätzlich noch eine liste, aus struct y (und struct y enthält struct x zeiger, diese zeigen alle auf die vorher schon erstelle liste bzw. objekte meiner liste)

    muss ich diese liste über ein malloc initiieren? oder nicht? die zeiger, auf die dieses struct y zeigen, sind alle schon über ein malloc erzeugt worden.

    Generell ist der Inhalt des Speicherbereichs völlig egal. free schaut sich nicht an, was da drinnen liegt (und für free selber ist es ja nur ein Haufen von Bytes ohne Bedeutung).

    Zitat

    wenn ich nun struct y "free" befehle, wirkt sich dass auch auf meine liste x aus?

    Gar nicht.

    Zitat

    wenn ich die struct y liste über malloc initiiert habe, muss ich sie ja mit free loswerden.

    Richtig.

    Zitat

    vielleicht muss ich aber gar nicht diese liste über ein malloc deklarieren, oder?

    Naja, irgendwoher muss der Speicher kommen, wo du das hinspeicherst. Speziell in C++ gibts da viele andere Methoden, aber in C greift man bei sowas eigentlich immer auf malloc zurück.

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • hal
    32
    hal
    Mitglied
    Reaktionen
    52
    Punkte
    11.122
    Beiträge
    2.208
    • 22. Dezember 2005 um 13:51
    • #16
    Zitat von sommeralex

    kann es vielleicht sein, dass ich nur den "speicher meines pointers" über free loswerden muss? also free(&pointer) ???

    nur wenn du den Speicher deines Pointers vorher alloziert hast mit malloc, also sowas in der Art wie &pointer = malloc(sizeof(&pointer));. Das geht aber nur in C++ mit seinen Referenzen.

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • sommeralex
    11
    sommeralex
    Mitglied
    Punkte
    1.325
    Beiträge
    188
    • 22. Dezember 2005 um 13:58
    • #17

    danke mal für die antwort.

    struct x{

    struct y *pointer;
    char[] reason;

    struct x *next;
    }

    struct y{

    int blabla;
    struct y *next;

    }

    ich erzeuge eine liste Y über malloc. dann iteriere ich über diese liste in gewissen abständen. falls manche objekte diese liste in meine auswahl kommen, möchte ich eine neue liste erstellen, mit einer struct X liste, in welcher zusätzlich der "grund"/reason gespeichert wird, warum dieses objekt aufgenommen wurde.

    also erstelle ich auch über malloc meine liste struct X. wenn ich nun ein "objekt" über free loswerden will, frage ich mich aber immer noch, was da WIRKLICH passiert? wenn sich das NICHT auf meine Y Liste auswirkt, was passiert dann überhaupt?

    Außerdem: wenn ich malloc X mache, bedeutet es doch, dass Speicherplatz sowohl für mein char[] als auch für meinen pointer next und pointer "pointer" RESERVIERT WIRD. da das objekt "pointer" aber sowieso schon besteht, ist es doch, als würde der platz "doppelt" bzw unnötig reserviert werden???

  • hal
    32
    hal
    Mitglied
    Reaktionen
    52
    Punkte
    11.122
    Beiträge
    2.208
    • 22. Dezember 2005 um 21:30
    • #18

    Du verwechselst den Speicherplatz, den der pointer selber beansprucht mit dem, auf den er zeigt. Ein Pointer ist eine Datenstruktur, die üblicherweise 4 Byte groß ist (auf 16bit-Systemen 2 Byte, auf 64bit-Systemen 8 Byte, etc). Auch dafür muss man Speicher reservieren.

    Nochmal: Stell dir vor da würde kein Pointer stehen, sondern ein int. Dann verwirrt es dich vielleicht weniger :)

    [font=verdana,sans-serif]"An über-programmer is likely to be someone who stares quietly into space and then says 'Hmm. I think I've seen something like this before.'" -- John D. Cock[/font]

    opentu.net - freier, unzensierter Informationsaustausch via IRC-Channel!
    Hilfe und Support in Studienangelegenheiten, gemütliches Beisammensein, von und mit Leuten aus dem Informatik-Forum!

  • Fup
    12
    Fup
    Mitglied
    Punkte
    1.460
    Beiträge
    291
    • 23. Dezember 2005 um 20:09
    • #19

    Vielleicht hilft es dir, wenn du einen passenden Debugger hernimmst und dir die Werte und Speicherbereiche anzeigen lässt. Ein selbstgetesteter Code sagt mehr als tausend Worte.

    mfG Fup

  • sommeralex
    11
    sommeralex
    Mitglied
    Punkte
    1.325
    Beiträge
    188
    • 24. Dezember 2005 um 08:58
    • #20

    welchen debugger empfehlt ihr?

    ps: vielen dank für die ständige hilfe + FROHE WEIHNACHTEN!!!!

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Rechtliches

Impressum

Datenschutzerklärung