Ist realloc bei unbedachter Benutzung nicht gefährlich?



  • zhjkl. schrieb:

    Einfach den Pointer vorher sichern

    That does the trick! 🙂



  • Beachte, dass realloc nicht automatisch mit 100, 100 mehr hat, sondern wieder genau hundert. Ist in deinem Beispiel nicht sehr ersichtlich.

    Desweiteren solltes du bei jeder Speicherallokationsfunktion den Rückgabewert behandeln und im kritischen Fall abbrechen.



  • Du kannst den Rückgabewert auch an einen temporären Zeiger geben und dann bei Erfolg umkopieren. Also z.b.

    char *buffer;
    char *temp;
    
    if(temp=realloc(buffer,100))
    {
    buffer=temp;
    temp = 0;
    }
    else
    {
    //Fehlerbehandlung
    }
    


  • Genau deine Lösung hatte ich vor Augen als ich diese eine Zeile gelesen hatte Wade1234 !!

    realloc sollte wenn, dann ca. so benutzt werden, und nicht so wie in meinem Beispiel.

    Danke für die Antworten!



  • Wenn du sehr pingelig sein willst lässt du sogar das temp = 0; weg würd ich mal meinen.



  • Also es ist (sehr) guter Programmierstil, nicht benutzte Zeiger auf 0 oder noch besser NULL zu setzen.



  • Nonsens. Das ist ein schlechter Programmierstil, da unnötige Abhängigkeiten aufgebaut werden (der aufrufende Kontext geht davon aus, dass (evtl. weit vorher) irgendeine Wertsetzung stattgefunden hat), das ist fehleranfällig und wartungskritisch.

    Der Definitionsbereich (insbesondere der von "Hilfs"variablen) ist immer maximal zu beschränken, dann kommt man gar nicht erst auf die Idee, Annahmen über irgendwelche Variablenwerte machen zu müssen:

    {
    char *buffer;
    ... /* viele Zeilen Code */ 
    {
      char *temp;
      if(temp=realloc(buffer,100))
      {
        buffer=temp;
      }
      else
      {
      //Fehlerbehandlung
      }
    }
    ... /* viele Zeilen Code */ 
    }
    


  • Es ist wirklich sehr guter Stil nicht mehr benutzte Zeiger auf 0 zu setzen, da doch ansonsten im Programm immernoch auf sie zugegriffen werden kann, denke ich.
    Aber Wutz's letzte Lösung scheint noch besser zu sein, Gültigkeitsbereiche von lokalen Variablen maximal zu beschränken. Dann braucht man wohl meistens auch nicht den Zeiger auf Null zu setzen.
    Aber ich frage mich was mit dem vorherigen Speicher von buffer passiert nachdem der Zeiger auf den Speicher von temp umgelenkt wurde. Müsste man vor der Zuweisung
    buffer=temp
    nicht vorher buffer = null machen, damit der alte Speicher freigegeben wird und kein Speicherleck entsteht?



  • cilker schrieb:

    Aber ich frage mich was mit dem vorherigen Speicher von buffer passiert nachdem der Zeiger auf den Speicher von temp umgelenkt wurde.

    Darum kümmert sich realloc automatisch. Im schlimmsten Fall werden die Daten in den neuen Speicher umkopiert und der Speicher gefree'd.

    Außer realloc gibt 0 zurück, aber dafür haste ja deinen temp* 🙂



  • cilker schrieb:

    Müsste man vor der Zuweisung
    buffer=temp
    nicht vorher buffer = null machen, damit der alte Speicher freigegeben wird und kein Speicherleck entsteht?

    Das ist nicht Java, d.h. es gibt weder null, noch wird Speicher dadurch freigegeben.
    Aber dadurch, dass buffer ja gleich wieder einen neuen Wert zugewiesen bekommt, hat man auch keine wilden Zeiger.

    Wutz schrieb:

    Nonsens. Das ist ein schlechter Programmierstil, da unnötige Abhängigkeiten aufgebaut werden (der aufrufende Kontext geht davon aus, dass (evtl. weit vorher) irgendeine Wertsetzung stattgefunden hat), das ist fehleranfällig und wartungskritisch.

    Also ich bin davon ausgegangen, dass jeder sofort sieht, dass das so kein lauffähiges Programm ist. 🙄

    Der Definitionsbereich (insbesondere der von "Hilfs"variablen) ist immer maximal zu beschränken, dann kommt man gar nicht erst auf die Idee, Annahmen über irgendwelche Variablenwerte machen zu müssen:

    {
    char *buffer;
    ... /* viele Zeilen Code */ 
    {
      char *temp;
      if(temp=realloc(buffer,100))
      {
        buffer=temp;
      }
      else
      {
      //Fehlerbehandlung
      }
    }
    ... /* viele Zeilen Code */ 
    }
    

    Ja das kann man so machen. Ich setze meine Variablen trotzdem weiterhin lieber ganz oben hin


  • Mod

    cilker schrieb:

    Aber ich frage mich was mit dem vorherigen Speicher von buffer passiert nachdem der Zeiger auf den Speicher von temp umgelenkt wurde. Müsste man vor der Zuweisung
    buffer=temp
    nicht vorher buffer = null machen, damit der alte Speicher freigegeben wird und kein Speicherleck entsteht?

    Irgendwelche Zeiger auf Null (oder sonstige Werte) zu setzen, hat überhaupt keine Auswirkungen auf die unterliegende Speicherverwaltung. In C sind Zeiger wirklich nur so etwas wie Zahlenwerte, ohne besondere Bedeutung. Da läuft kein magischer Überwachungsprozess (z.B. Garbage Collector) im Hintergrund, der Speicher freigibt, wenn man einen Zeiger auf Null setzt, oder ähnliches. Sämtliche dynamische Speicherverwaltung geschieht nur (und nur!) über malloc, free & Co.

    Folglich ist all dieses Nullsetzen aus Sicherheitsgründen dem Bereich der Mythen zuzuschreiben. Verbreitet von schlechten Lehrern, die kein korrektes Programm schreiben könnten, aber mit dem Nullsetzen wenigstens noch ein paar Fehler vertuschen. Wahrscheinlich haben sie mal gesehen, wie ein echter Programmierer mal Nullzeiger eingesetzt hat, um z.B. selbst erstellte Datenstrukturen zu terminieren, aber haben nicht so ganz verstanden, warum er das gemacht hat.



  • @Sepp gut das ist wohl wahr, C hat keinen Garbage Collector,
    müsste man aber dann nıcht erstmal free(buffer) machen bevor man buffer = temp setzt? Wäre das jetzt ohne free(buffer) in einem vorherigen Schritt nicht ein typischer Fall eines Speicherlecks? Doch, oder?


  • Mod

    cilker schrieb:

    @Sepp gut das ist wohl wahr, C hat keinen Garbage Collector,
    müsste man aber dann nıcht erstmal free(buffer) machen bevor man buffer = temp setzt? Wäre das jetzt ohne free(buffer) in einem vorherigen Schritt nicht ein typischer Fall eines Speicherlecks? Doch, oder?

    Nein, dann wären doch die Daten futsch!

    realloc gibt den alten Speicher frei, falls umgelagert wird. Das ist in der Spezifikation von realloc so vorgeschrieben. Außer eben in dem Fall, wenn realloc keinen neuen Speicher bekommen konnte (also das Thema dieses Threads), da wird natürlich nicht der alte Speicher freigegeben, wenn kein neuer da ist, denn sonst hätte man in dem Fall schließlich alles verloren.


Anmelden zum Antworten