Doppelpointer: Speicherplatz freimachen mit free, nur wie?



  • Hallo,

    kann ich denn einen Doppelpointer so freimachen? Oder gibt es vielleicht andere Möglichkeiten?

    int **array = (int**)malloc(2*sizeof(int*));
    
    for(int i =0; i<10;++i){
      array[1] = (int*)realloc(array[i],sizeof(int)*(i+1));
      *(array[1]+i)) = i*3;
      array[2] = (int*)realloc(array[i],sizeof(int)*(i+1));
      *(array[2]+i) = i+8;
    }
    
    for(int j=0;j<2;++j){
      if(array[j]){
        free (array[j])
        array[j] = NULL;
      }
    }
    
    if(array){
      free(array);
      array = NULL;
    }
    


  • eine andere möglichkeit weis ich auch nicht, habe mir allerdings ein makro geschrieben und die sache abzukürzen.

    #define SAFE_FREE(p)            { if(p) { free(p); (p) = 0; }}
    
    for(int j=0;j<2;++j)
     SAFE_FREE(array[j]);
    
    SAFE_FREE(array);
    


  • free prüft intern selbst, ob der übergebene Zeiger ein Nullpointer ist. Zitat aus dem C-Standard: «If ptr is a null pointer, no action occurs.» Das Nullsetzen des Zeigers danach ist Geschmackssache, IMHO unnötig, da es Fehler verschleiern kann.



  • Bashar schrieb:

    free prüft intern selbst, ob der übergebene Zeiger ein Nullpointer ist. Zitat aus dem C-Standard: «If ptr is a null pointer, no
    action occurs.»

    wusste ich nicht 😃

    Bashar schrieb:

    Das Nullsetzen des Zeigers danach ist Geschmackssache, IMHO unnötig, da es Fehler verschleiern kann.

    in wiefern ?



  • Doppeltes freigeben wird so nicht gefunden, dürfte aber ziemlich sicher auf einen Logikfehler im Programm zurückzuführen sein. Also ist es besser, in der Entwicklungszeit im Fall des Falles einen Absturz zu riskieren und dann den Fehler zu beseitigen, als ihn ewig unerkannt mitzuschleppen.



  • Weiter Unklarheit:

    Kann ich den array so in einen neuen reinkopieren?

    NeuArrayDoppelpointer = (int**)malloc(sizeof(int*)*2);
    memcpy(NeuArrayDoppelpointer,array,sizeof(int)*10);
    

    oder brauch ich ne Schleife?

    for(int i=0;i<2;++i){
      memcpy(NeuArrayDoppelpointer[i],array[i],sizeof(int)*10);
    }
    


  • miller_m schrieb:

    Bashar schrieb:

    Das Nullsetzen des Zeigers danach ist Geschmackssache, IMHO unnötig, da es Fehler verschleiern kann.

    in wiefern ?

    Wenn du einen gelöschten Zeiger nochmals löscht, hast du einen Fehler im Programmablauf. Wenn du den Zeiger auf auf 0 gesetzt hast, merkst du es nicht. Wenn du es nicht auf 0 gesetzt hast, bekommst du ne Access Violation (oder etwas ähnliches) - du bemerkst den Fehler also und kannst ihn beseitigen. Und da ein Fehler selten alleine kommt, wirst du neben dem fehlerhaften free() sicher auch noch andere Sachen entdecken die dann nicht ganz so sein sollten.



  • ga_un schrieb:

    Kann ich den array so in einen neuen reinkopieren?

    NeuArrayDoppelpointer = (int**)malloc(sizeof(int*)*2);
    memcpy(NeuArrayDoppelpointer,array,sizeof(int)*10);
    

    oder brauch ich ne Schleife?

    for(int i=0;i<2;++i){
      memcpy(NeuArrayDoppelpointer[i],array[i],sizeof(int)*10);
    }
    

    Du hast nicht genug speicher... NeuArrayDoppelpointer hat nur Speicher für 2 int* du willst aber zwei int[10] Arrays reinkopieren - das kann nicht gut gehen.

    Beide Codestücke sind somit falsch.



  • Aber so paßt's, oder???

    for(int i=0;i<2;++i){
      NeuArrayDoppelpointer[i] = (int*) calloc(10,sizeof(int));
      memcpy(NeuArrayDoppelpointer[i],array[i],sizeof(int)*10);
    }
    


  • Shade Of Mine schrieb:

    miller_m schrieb:

    Bashar schrieb:

    Das Nullsetzen des Zeigers danach ist Geschmackssache, IMHO unnötig, da es Fehler verschleiern kann.

    in wiefern ?

    Wenn du einen gelöschten Zeiger nochmals löscht, hast du einen Fehler im Programmablauf. Wenn du den Zeiger auf auf 0 gesetzt hast, merkst du es nicht. Wenn du es nicht auf 0 gesetzt hast, bekommst du ne Access Violation (oder etwas ähnliches) - du bemerkst den Fehler also und kannst ihn beseitigen. Und da ein Fehler selten alleine kommt, wirst du neben dem fehlerhaften free() sicher auch noch andere Sachen entdecken die dann nicht ganz so sein sollten.

    somit wäre es vollkommen ausreichend "free(array);" zuschreiben. ?!?



  • ga_un schrieb:

    Aber so paßt's, oder???

    for(int i=0;i<2;++i){
      NeuArrayDoppelpointer[i] = (int*) calloc(10,sizeof(int));
      memcpy(NeuArrayDoppelpointer[i],array[i],sizeof(int)*10);
    }
    

    ja, allerdings wäre malloc statt calloc besser - da du den Inhalt ja nicht 0 setzen musst, da er ja sowieso gleich überschrieben wird.

    @miller_m:
    ja, free(array); finde ich schöner als
    if(array) { free(array); array=0; }

    Die Schleife für array[i] muss natürlich trotzdem drinnen bleiben...



  • @shade of mine und bashar
    ich danke euch, wieder was gelernt. 😃



  • vielleicht ne blöde Zwischenfrage,
    aber gehört das nich eher in ANSI C ?


Log in to reply