wie weiss delete[] array die Array Grösse



  • Vielen Dank für die angeregte Diskussion, da wurden für mich sehr interessante Punkte angesprochen.

    Ich fasse das für mich dann, der Einfachheit zuliebe, so zusammen:
    für die C oder C++ runtime ist die Größen-Infromation zwar da,
    man hat aber entschieden diese nicht zugänglich zu machen,
    oder darauf vergessen und das nie repariert,
    zumindest bei den Array Typen wo die Information sowieso verfügbar ist,
    es aber möglich ist das reservierter Bereich größer ist als vom User angefordert und im dem Fall der User wissen/-buchhalten muss wo sein letztes gültiges Element ist.
    Wobei, wenn ich Platz für 10 anfordre, und aus Gründern der Optimierung Platz für 11 zurückbekommen sollte, dann sollte man mir dies Information doch auch nicht vorenthalten?

    Nunja, warum repariert man das eigentlich in den ganzen Standard Komitee Sitzungen nicht, zu trivial?



  • kurze_frage schrieb:

    Nunja, warum repariert man das eigentlich in den ganzen Standard Komitee Sitzungen nicht, zu trivial?

    welchen zweck hätte das denn? und was würde passieren wenn

    int x[]=new int[256];
    delete[23] x;
    


  • HansKlaus schrieb:

    ...
    delete[23] x;
    

    Bittewas?

    kurze_frage: Die Größe eines Arrays ermittelst du mit sizeof(arr)/sizeof(T).



  • Den Mist oben ignorieren, hier gehts ja um Speicherreservierung 💡



  • @HansKlaus
    Es gäbe ja mehrere Arten wie man es reparieren kann.
    WENN man die Variante wählt dass man bei delete[] selbst mitgeben muss wie viele Elemente es gibt (was mMn. nicht die beste Variante ist), dann würde in deinem Beispiel das selbe passieren wie z.B. bei

    char* p = new char[123];
    delete p;
    delete p; // undefined behavior
    

    oder auch

    char* p = new char[123];
    p++;
    delete p; // undefined behavior
    


  • HansKlaus schrieb:

    kurze_frage schrieb:

    Nunja, warum repariert man das eigentlich in den ganzen Standard Komitee Sitzungen nicht, zu trivial?

    welchen zweck hätte das denn? und was würde passieren wenn

    int x[]=new int[256];
    delete[23] x;
    

    nein, natürlich nicht

    tippender schrieb:

    kurze_frage: Die Größe eines Arrays ermittelst du mit sizeof(arr)/sizeof(T).

    also ich mach das nicht so gerne mit dynamischen arrays (welche ich sowieso nicht verwende wenn ich nicht muss)

    char* p = new char[123] ;
     std::cout << sizeof(p)/sizeof(char) ;
    

    das ist nicht die Größe eines Arrays

    brauchbar wäre doch eher

    char* p = new char[123] ;
       arraySize(p) ; // 123 
    
       arraySize(++p) ; // ?? oder eventuell 0
    

    wenn delete[] (p) die grösse weiß,
    warum nicht eine arraySize(p) Methode die es mir verrät?

    es ist doch nicht konsequent, symmetrisch, schön und nützlich eine solche Funktion nicht zu haben.
    Denk ich mir halt, ich und wollte wissen ob es fundierte Gründe gibt das uns diese Funktion, eventuell mit einem anderen Namen, vorenthalten wird.



  • Nunja, warum repariert man das eigentlich in den ganzen Standard Komitee Sitzungen nicht, zu trivial?

    ballast aus alten tagen, den man nicht so einfach über bord werfen kann, ohne vielen leuten das leben schwer und die brieftasche leicht zu machen.
    da erfindet man lieber neue konstrukte und wartet zunächst ein paar (zehn oder mehr) jahre, bevor man die alten aufgibt. (z.b. char*x="lit" vs const char*x="lit"), und das ist auch gut so.

    in der zwischenzeit sollte man eben, so gut es geht, auf manuelle dynamische speicherverwaltung verzichten. std::vector z.b. bietet alles, was man braucht:

    std::vector<char> array;
    
    array.reserve(42);
    array.resize(23);
    
    array.size();
    array.capacity();
    


  • HansKlaus schrieb:

    welchen zweck hätte das denn? und was würde passieren wenn
    [code]
    int x[]=new int[256];
    delete[23] x;

    Es hätte den Zweck / Vorteil, dass der, der sich die Länge selber speichert, oder bei dem die Länge eine Konstante ist, nicht für den overhead zahlen muss.

    Wenn die falsche Länge beim Freigeben angegeben wird, dann würde das C++-übliche "undefined behaviour" zuschlagen.

    Dynamisch erzeugte arrays ist doch so ein spezial-Fall, den doch kaum noch jemand nutzt.



  • welchen overhead? irgendwo muss doch sowieso gespeichert werden, wie groß das array ist, weil das betriebssystem sonst gar nicht weiß, wie viel speicher es noch zur verfügung hat.

    c++-übliches undefined behaviour? also ich weiß, dass die cpu "mal eben so" einen neustart durchführt, wenn sie nicht-definierte zustände feststellt, weil so etwas den supergau schlechthin darstellt.
    aber eigentlich wird mit delete nur ein tabelleneintrag in der form "anfangsadresse, endadresse" gelöscht, von daher gibt es da auch keine fehlermöglichkeit.

    dynamische arrays werden schon benutzt, bei typischen anwendungsfällen von c++ allerdings eher unsichtbar für den benutzer.



  • HansKlaus schrieb:

    welchen overhead? irgendwo muss doch sowieso gespeichert werden, wie groß das array ist, weil das betriebssystem sonst gar nicht weiß, wie viel speicher es noch zur verfügung hat.

    Das Betriebssystem hat in der Regel überhaupt nichts mit dem Allocator aus der C++ Runtime Library zu tun (ausser das sich der Allocator dort Speicher holt). Und der Allocator muss sich nicht merken, wie groß ein dynamisch alloziiertes Array ist, wenn er die Informationen beim Freigeben wieder mit bekommt.

    Wenn der Allocator gezwungen wird, diese Informationen zu speichern, dann sind diese Informationen zwangsläufig nur noch zur Laufzeit bekannt. Jede Optimierung, die möglich wäre, weil die Informationen bereits zur compile-Zeit bekannt sind, werden damit unmöglich.

    HansKlaus schrieb:

    c++-übliches undefined behaviour? also ich weiß, dass die cpu "mal eben so" einen neustart durchführt, wenn sie nicht-definierte zustände feststellt, weil so etwas den supergau schlechthin darstellt.

    "undefined behaviour" ist ein stehender Begriff in der C++-Welt. Das ist unbedingt zu vermeiden und es hat sich auch keiner die Mühe gemacht, zu definieren, was in solchen Situationen zu passieren hat. double delete ist z.B. auch so ein Fall. Bei einer "üblichen" Implementierung eines heaps, wir ein frei gewordenes Stück Speicher einfach in eine Liste freier Speicher mit einer bestimmten Größe gehängt. Ein double delete führt in dem Fall dann einfach dazu, dass der gleiche Speicher zwei mal in der Liste hängt.

    HansKlaus schrieb:

    aber eigentlich wird mit delete nur ein tabelleneintrag in der form "anfangsadresse, endadresse" gelöscht, von daher gibt es da auch keine fehlermöglichkeit.

    Wer diese Informationen von der C++ Runtime haben möchte, kann doch einfach std::vector verwenden.


Anmelden zum Antworten