delete



  • TactX schrieb:

    Was ist der Unterschied zwischen *int foo = new int; und int *foo = new int[bar];?

    Hi,
    damit wollte dich TactX wohl auf Arrays aufmerksam machen 😉

    Beispiel:

    int *single_pointer = new int;
       //... mach was damit ...
       delete single_pointer;
    
       int *pointer_array = new int[10];
       //... mach was mit den Pointern ...
       delete [] pointer_array;
    


  • bei 'nem array aus int's sollte das egal sein. nur wenn man c++ objekte mit 'new' erzeugt spielt das '[]' 'ne rolle, damit auch alle destruktoren aufgerufen werden.
    btw: bitte berichtigt mich c++ -noob, falls das falsch ist...



  • Es sollte eigentlich nicht egal sein.
    Mit

    delete array_pointer;
    

    wird nur der erste Pointer freigegeben.



  • ich mag mich täuschen, aber als c-coder (mit wenig ++ erfahrung) glaube ich dass:

    int *a = new int;
    int *b = new int[1000];
    delete a; // ok
    delete b; // offensichtlich falsch aber geht trotzdem
    

    gehen sollte...

    aber tun' sollte man wowas natürlich trotzdem nicht 😉



  • Wenn die Implementierung von new und delete auf malloc und free zurückgreift, ist es für triviale Objekte wohl tatsächlich egal, da man bei free auch nur den Zeiger und nicht dessen Größe zum freigeben braucht.

    Aber: Der Standard macht dieses Zugeständnis nicht, so dass dieses Verfahren dann nicht mehr portabel ist.

    @nucknuck:
    Ein "falsches" delete ist imho schlicht und ergreifend als undefiniert anzusehen. Nur den "ersten" Pointer freizugeben (wobei das im Grunde nicht stimmt, denn es gibt nur einen Pointer auf einen zusammenhängenden Block mehrerer ints) dürften die wenigsten Freispeicherverwaltungen unterstützen 😉



  • LordJaxom schrieb:

    Freispeicherverwaltungen

    was für ein wort 😉



  • eigentlich isses ja einfach zu erklaeren

    // reserviert speicher fuer 1xint
    int *a = new int;

    // reserviert speicher fuer 3xint
    int *b = new int[3];

    //nu schreibt man die werte voll in a die 1 und in b 1, 2 und 3
    //nu wieder freigeben

    // den speicherbereich des ersten (und in diesen fall einzigsten] bereich freigeben
    delete a;

    // falsch, denn man loescht nur den anfang, also die 1, aber 2 und 3 bleibt unbenutzt im speicher rumliegen
    //delete b;

    // darum mit [] damit man sagt "gib alle reservierten bereiche frei"
    delete[] b;

    //am bestem am ende noch;
    a = NULL;
    b = NULL;

    int *a = new int;
    int *b = new int[300];
    // fuellen blablubb
    if( a != NULL ){
        delete a;
        a = NULL;
    }
    if( b != NULL ){
        delete[] b;
        b = NULL;
    }
    

    die "ifs" sind einfach nur - fals man durch bloede zufaelle wegen diversen ablaeufen den zeiger schon geloescht hat

    auch fuer die zugriffe sollte man sagen

    if( pointer != NULL )
    oder
    if( pointer == NULL ) return - je nachdem, damit man immer mit gueltigen pointern arbeitet



  • Mr Evil schrieb:

    die "ifs" sind einfach nur - fals man durch bloede zufaelle wegen diversen ablaeufen den zeiger schon geloescht hat

    Die if()s sind vor allem unnötig (delete auf einen NULL-Zeiger ist erlaubt und macht gar nichts) und täuschen eine nicht vorhandene Sicherheit vor (wenn jemand anderes deinen Scpeicher freigegeben hat, bekommst du gar nichts davon mit - insbesondere werden auch fremde Pointer, die dorthin zeigen, nicht zurückgesetzt).

    PS: Im Magazin findet ihr einen Artikel über Speicherverwaltung - wen's interessiert, der soll da mal reinschauen 😉



  • Mr Evil schrieb:

    // falsch, denn man loescht nur den anfang, also die 1, aber 2 und 3 bleibt unbenutzt im speicher rumliegen
    //delete b;

    Wie schon geschrieben Implementationsabhängig - und den Anfang eines zusammenhängenden Blocks freigeben kann imho keine gängige Speicherverwaltung - vom Gegenteil möge man mich überzeugen.

    Jedenfalls bleibt in keiner mir bekannten Umgebung der hintere Teil eines Blockes "unbenutzt im Speicher".

    Anyway, einigen wir uns doch einfach drauf dass das undefiniert ist. 😉



  • LordJaxom schrieb:

    Jedenfalls bleibt in keiner mir bekannten Umgebung der hintere Teil eines Blockes "unbenutzt im Speicher".

    ich kann mich zwar taeuschen, aber wenn ich beim debuggen mir anschau was im speicher steht {window->memory1} und das delete ohne den [] mach - wird nur das erste geloescht, aber der rest bleibt drinne

    gleich nochmal ausprobieren #gg

    //dazuedit

    getestet hab

    int _tmain(int argc, _TCHAR* argv[])
    {
    	int *a = new int;
    	*a = 1;
    	delete a;
    	a = NULL;
    
    	int *b = new int[3];
    	*b = 1;
    	*(b+1) = 2;
    	*(b+2) = 3;
    	delete b;
    	b = NULL;
    
    	return 0;
    }
    

    ich werd nich mehr - der speicher ist ja wirklich komplett geleert ohne dem [] - meine welt stuerzt grad in sich zusammen #gg



  • Ich würde auf solche Spielchen trotzdem nicht eingehen. Der Standard definiert ganz klar, dass zu new delete gehört, und zu new[] delete[]. Alles andere ist nicht definiert.



  • Mr Evil schrieb:

    ...wenn ich beim debuggen mir anschau was im speicher steht ...

    Was Dir groovemaster aber sagen will: Das mag gut sein, aber es kann bei anderen Compileoptionen, der nächsten Compilerversion, einem anderen Compiler/Betriebssystem/Tagesstimmung der Runtimelib, .... gaaaanz anders sein.
    Ergo: Du kannst Dich nicht drauf verlassen.... und solltest es deswegen lieber nicht.

    Gruß,

    Simon2.


Anmelden zum Antworten