gibt es eine sichere Methode für "free"



  • Guten Abend,

    also wenn ich mit "free" versuche einen Buffer zu "befreien" dem kein Speicher mit malloc zugewiesen wurde, crasht mein Programm. Bei einem einzigen Buffer ist das noch überschaubar und man mach ganz einfach

    char   *buffer = NULL;
    

    und schon gehts, wird ein Programm jedoch länger und der Buffer ist in einer Struktur, mache ich das immer so

    if(struct->buffer){
        free(struct->buffer);
        struct->buffer = NULL;
    }
    

    sitzt jetzt irgendwo hinten im Programm noch ein free, haut mir das dann nicht ins Kreuz, weil ich es ja genauso aufrufe. Daher die Frage gibt es irgendeine Möglichkeit die Speicheradresse freizugeben ohne zu wissen ob sie "mallociert" ist?



  • wenn du den speicher immer selber allokiertst, kannst du eine liste der allokierten speicherbereiche führen oder größere blocks holen und markieren.



  • ANSI Hansi schrieb:

    Daher die Frage gibt es irgendeine Möglichkeit die Speicheradresse freizugeben ohne zu wissen ob sie "mallociert" ist?

    leider nicht, das einzige was 'free' ohne zicken schluckt sind nullen. du könntest natürlich funktionen benutzen, die in jeden speicherblock 'ne markierung einbauen, so in etwa:

    #define MAGIC_NUMBER 11039945    // irgendeine zahl, aber nicht 0 oder sowas
    
    void *my_malloc (size_t size)
    {
       int *p = malloc (size+sizeof(int));   // speicher für ein int mehr
       if (p == 0)                            
          return 0;                          // raus, falls malloc fehlschlug
       *p = MAGIC_NUMBER;                    // magic number eintragen 
       return p + 1;                         // return pointer auf speicher nach der MN
    }
    ...
    void my_free (void *ptr)
    {
       int *p = ((int*)ptr)-1;              // pointer auf magic number setzen
       if (*p == MAGIC_NUMBER)              // ist sie da?
       {
          *p = 0;                           // gefunden, löschen (wegen mehrfachen aufrufen)
          free (p);                         // und freigeben
       }                                    
       else
       {                                    // andernfalls fehlerausgabe oder nix machen
          debug_printf ("my_free() got a bogus pointer\n");
       }
    }
    

    ^^ungetestet, aber prinzip dürfte klar sein: wird 'my_free' mit irgendwelchen schrottpointern (pointer müssen natürlich trotzdem auf einen bereich zeigen, auf den dein programm lesezugriff hat) aufgerufen, passiert höchstwahrscheinlich nix schlimmes, weil die 'magic number' nicht gefunden wird.
    🙂



  • ANSI Hansi schrieb:

    Guten Abend,

    also wenn ich mit "free" versuche einen Buffer zu "befreien" dem kein Speicher mit malloc zugewiesen wurde, crasht mein Programm. Bei einem einzigen Buffer ist das noch überschaubar und man mach ganz einfach

    char   *buffer = NULL;
    

    Wenn Du jedem Zeiger bei der Definition einen vernünftigen Initialisierungswert zuweist (also entweder einen 'echten' Wert oder aber NULL), dann sollte das Problem nicht auftreten, denn auf einen NULL-Zeiger kannst Du ohne Probleme free aufrufen - wie auch Fricky schon schrob.
    Nach einem Aufruf von free dann dem Zeiger wieder NULL zuweisen, und Du kannst die

    if(struct->buffer){
        free(struct->buffer);
        struct->buffer = NULL;
    }
    

    if-Abfrage sparen - zumindest solange sie nur dazu dient, einen Crash zu verhindern - natürlich hat sie weiterhin die Berechtigung, einen unnötigen Aufruf von free zu verhindern.


Log in to reply