Wie gebe ich einen const Zeiger wieder frei?



  • Ich habe eine Struct Liste erstellt und für das erste Listenelement einen const Zeiger erstellt, weil ich nicht haben will, daß die Adresse des ersten Listenelements ausversehen verloren geht oder überschrieben wird.

    struct liste
      {
          char* str;  // Enthält den Zeiger auf einen C String
          struct liste *next; // Enthält den Zeiger zum nächsten Listenelement
      };
    
      struct liste *hilf;  // Hilf ist mein Zeiger mit dem ich arbeite
      struct liste const *listenanfang = (struct liste*) malloc(sizeof (struct liste));  // Die Adresse auf den dieser Zeiger zeigt, soll nicht verloren gehen, daher const
      hilf = (struct liste*) listenanfang; // Da zu Beginn mit dem ersten Listenelement gearbeitet wird, wird die Adresse von Listenanfang nach hilf kopiert
    
      /* Viel Code ....*/
    
      /* Speicherbereinigung mit weiterem Code bei der alle Listenaufträge bis auf den erste freigegeben bzw. gelöscht werden*/
    
      /* Ganz am Ende will ich noch den Speicher auf den listenanfang zeigt freigeben */
      free (listenanfang);
      return 0;
    }
    

    Das Problem ist jetzt, wenn ich den Zeiger freigeben will, daß ich folgende Fehlermeldung erhalte:

    warning: passing argument 1 of ‘free’ discards qualifiers from pointer target type
    

    wenn ich den const Zeiger listenanfang aber in einen (void*) caste, dann geht es:

    free( (void*) listenanfang);
    

    Frage:

    Ist das so überhaupt zulässig bzw. gedacht?



  • Hallo,

    const verhindert nicht, daß Dein Zeiger verloren geht. Das geht trotzdem. Er verhindert nur, daß der Inhalt, auf den der Zeiger verweist, verändert wird. Diesen Schutz hast Du aber ausgehebelt, indem Du den const Zeiger einem normalen Zeiger zuweist.

    Damit ist das const für die Katz und Du kannst es weglassen. Die Katze kann damit nämlich nix anfangen, die will nur Mäuse.

    mfg Martin



  • mgaeckler schrieb:

    Hallo,

    const verhindert nicht, daß Dein Zeiger verloren geht. Das geht trotzdem. Er verhindert nur, daß der Inhalt, auf den der Zeiger verweist, verändert wird.

    Das steht hier aber anders dran:

    http://www.mathematik.uni-marburg.de/~cpp/pointer/const.html

    Man kann entweder die Adresse auf den der Zeiger verweist konstant machen,
    oder die Daten, die diese Adresse enthalten.
    Oder man macht beides.
    Entscheident ist, wo "const" steht.

    Diesen Schutz hast Du aber ausgehebelt, indem Du den const Zeiger einem normalen Zeiger zuweist.

    Die Daten zu verändern ist ja nicht das schützenswerte, sondern die Adresse des ersten Listenelelements.

    Wo hilf später hinzeigt ist egal, der listenanfang zeiger wird immer noch, da er konstant ist, auf das erste Listenelement zeigen.
    Auch wenn dessen Inhalt verändert wurde oder leer ist.

    Ein Problem gibt's IMO eigentlich nur dann, wenn ich das erste Listenelement über den Hilf Zeiger lösche bzw. den Speicher freigebe.

    Dann zeigt der listenelement Zeiger nämlich noch auf eine Adresse, dessen Speicherbereich schon längst freigegeben wurde.

    Damit ist das const für die Katz und Du kannst es weglassen. Die Katze kann damit nämlich nix anfangen, die will nur Mäuse.

    Wie soll ich dann die Adresse des ersten Listenelements schützen?



  • char Zeiger schrieb:

    Ich habe eine Struct Liste erstellt und für das erste Listenelement einen const Zeiger erstellt, weil ich nicht haben will, daß die Adresse des ersten Listenelements ausversehen verloren geht oder überschrieben wird.

    Naja, ob const in C (!) dir diese Gewissheit gibt, sei mal dahingestellt. Jedenfalls deklarierst du hier einen Zeiger auf eine konstante Struktur, keinen konstanten Zeiger. Der müsste so aussehen:

    struct liste* const listenanfang = malloc(sizeof(struct liste));
    

    (ohne Cast natürlich)

    struct liste *hilf;  // Hilf ist mein Zeiger mit dem ich arbeite
      struct liste const *listenanfang = (struct liste*) malloc(sizeof (struct liste));  // Die Adresse auf den dieser Zeiger zeigt, soll nicht verloren gehen, daher const
      hilf = (struct liste*) listenanfang; // Da zu Beginn mit dem ersten Listenelement gearbeitet wird, wird die Adresse von Listenanfang nach hilf kopiert
    

    Hast du dich mal gefragt, wieso du da einen Cast hingeschrieben hast? Also warum der notwendig ist?



  • [quote="Bashar"]

    char Zeiger schrieb:

    Ich habe eine Struct Liste erstellt und für das erste Listenelement einen const Zeiger erstellt, weil ich nicht haben will, daß die Adresse des ersten Listenelements ausversehen verloren geht oder überschrieben wird.

    Naja, ob const in C (!) dir diese Gewissheit gibt, sei mal dahingestellt. Jedenfalls deklarierst du hier einen Zeiger auf eine konstante Struktur, keinen konstanten Zeiger. Der müsste so aussehen:

    struct liste* const listenanfang = malloc(sizeof(struct liste));
    

    (ohne Cast natürlich)
    [/QUOTE}

    Ach so, ok. Wieder etwas gelernt.
    Ich dachte ich hätte hier einen konstanten zeiger auf eine variable Struktur.

    struct liste *hilf;  // Hilf ist mein Zeiger mit dem ich arbeite
      struct liste const *listenanfang = (struct liste*) malloc(sizeof (struct liste));  // Die Adresse auf den dieser Zeiger zeigt, soll nicht verloren gehen, daher const
      hilf = (struct liste*) listenanfang; // Da zu Beginn mit dem ersten Listenelement gearbeitet wird, wird die Adresse von Listenanfang nach hilf kopiert
    

    Hast du dich mal gefragt, wieso du da einen Cast hingeschrieben hast? Also warum der notwendig ist?

    Naja, ich habe das zuerst etwas umbauen müssen, vorher waren's 2 Zeilen mehr und weil der Compiler warnings war, hab ich halt rumprobiert.



  • const Zeiger schrieb:

    struct liste *hilf;  // Hilf ist mein Zeiger mit dem ich arbeite
      struct liste const *listenanfang = (struct liste*) malloc(sizeof (struct liste));  // Die Adresse auf den dieser Zeiger zeigt, soll nicht verloren gehen, daher const
      hilf = (struct liste*) listenanfang; // Da zu Beginn mit dem ersten Listenelement gearbeitet wird, wird die Adresse von Listenanfang nach hilf kopiert
    

    Hast du dich mal gefragt, wieso du da einen Cast hingeschrieben hast? Also warum der notwendig ist?

    Naja, ich habe das zuerst etwas umbauen müssen, vorher waren's 2 Zeilen mehr und weil der Compiler warnings war, hab ich halt rumprobiert.

    Ich glaube ich weiß es jetzt wieder. So habe ich mir einen Variablennamen gespart.

    Denn liste ist im Prinzip ja ein Typ und keine Variable.

    struct liste = malloc(sizeof (struct liste));
    

    Hätte also nicht wirklich funktioniert, denn wem hätte man den Wert auf der rechten Seite ansonsten zuweisen sollen und wie hätte ich dann den Zeigern gesagt, wo die hinweisen sollen?
    Und da ich sowieso nur Zeiger brauche, dachte ich.
    Ok, dann caste ich das gleich in einen Zeiger.

    Und spar mir so etwas wie

    struct liste unnoetiger_redunanter_Ballast = malloc(sizeof (struct liste));
    


  • const Zeiger schrieb:

    Wie soll ich dann die Adresse des ersten Listenelements schützen?

    Vergiß den Stuß, den ich geschrieben habe, hör lieber auf Bashar. Heut' ist nicht mein Tag. 😞

    mfg Martin



  • const Zeiger schrieb:

    Wie soll ich dann die Adresse des ersten Listenelements schützen?

    So:

    struct liste * const listenanfang = (struct liste*) malloc(sizeof (struct liste));  // Die Adresse auf den dieser Zeiger zeigt, soll nicht verloren gehen, daher const
    

Anmelden zum Antworten