Frage

Wenn Sie ein Array verwenden, verwenden Sie new [], Warum können Sie die Größe dieses Arrays aus dem Zeiger nicht herausfinden? Es muss zur Laufzeit bekannt sein, sonst delete [] Ich würde nicht wissen, wie viel Erinnerung frei ist.

Es sei denn, mir fehlt mir etwas?

War es hilfreich?

Lösung

In einer typischen Implementierung wird die Größe des dynamischen Speicherblocks irgendwie im Block selbst gespeichert - dies ist wahr. Es gibt jedoch keinen Standard -Weg, um auf diese Informationen zuzugreifen. (Implementierungen können implementierungsspezifische Möglichkeiten bieten, um darauf zuzugreifen). So ist es mit malloc/free, So ist es mit new[]/delete[].

In der Tat in einer typischen Implementierung RAW -Speicherzuweisungen für new[]/delete[] Anrufe werden schließlich von einigen implementierungsspezifischen verarbeitet malloc/free-ähnliches Paar, was das bedeutet delete[] Es muss sich nicht wirklich darum kümmern, wie viel Gedächtnis an die Handlungsbewegung ist: Es nennt das einfach intern free (oder was auch immer es genannt wird), was sich darum kümmert.

Was delete[] muss jedoch wissen, wie viele Elemente zu Zerstörung In Situationen, in denen Array-Elementtypen nicht trivialen Destruktor aufweist. Und darum geht es in Ihrer Frage - - die Anzahl der Array -Elemente, nicht die Größe des Blocks (diese beiden sind nicht gleich, der Block könnte größer sein als für das Array selbst erforderlich). Aus diesem Grund wird die Anzahl der Elemente im Array normalerweise auch im Block von gespeichert new[] und später abgerufen durch delete[] Um die richtige Zerstörung des Array -Elements durchzuführen. Es gibt auch keine Standardmethoden, um auf diese Nummer zuzugreifen.

(Dies bedeutet, dass im allgemeinen Fall ein typischer Speicherblock von zugewiesenen von zugewiesener Fall ist new[] wird unabhängig voneinander speichern beide die physische Blockgröße in Bytes und Das Array -Element zählt. Diese Werte werden durch verschiedene Ebenen des C ++ -Remory -Allokation -Mechanismus gespeichert - RAW -Speicher -Allocator und new[] selbst selbst - und interagieren in keiner Weise miteinander).

Beachten Sie jedoch, dass aus den oben genannten Gründen die Anzahl der Array-Elemente normalerweise nur gespeichert wird, wenn der Array-Elementtyp nicht-triviale Destruktor hat. Dh diese Anzahl ist nicht immer vorhanden. Dies ist einer der Gründe, warum es nicht möglich ist, eine Standardmethode für den Zugriff auf diese Daten zu bieten: Sie müssten sie entweder immer speichern (was den Speicher verschwendet) oder die Verfügbarkeit durch Destruktor -Typ (was verwirrend ist) einschränken.

Um die oben genannten zu veranschaulichen, wenn Sie ein Array von erstellen ints

int *array = new int[100];

die Größe des Arrays (dh 100) ist nicht Normalerweise gespeichert von new[] seit delete[] kümmert sich nicht darum (int hat keinen Destruktor). Die physikalische Größe des Blocks in Bytes (wie 400 Bytes oder mehr) wird normalerweise vom Rohspeicher -Allocator (und vom RAW -Speicher -Deallocator verwendet, der von aufgerufen wird von RAW Memory verwendet wird delete[]), aber es kann sich aus einem implementierungsspezifischen Grund leicht als 420 herausstellen. Diese Größe ist für Sie im Grunde genommen nutzlos, da Sie die genaue ursprüngliche Array -Größe nicht daraus abgeben können.

Andere Tipps

Sie können höchstwahrscheinlich darauf zugreifen, aber es wäre intimes Wissen über Ihren Allocator und wäre nicht tragbar. Der C ++ - Standard wird nicht angegeben wie Implementierungen speichern diese Daten, daher gibt es keine konsistente Methode, um sie zu erhalten. Ich glaube, es ist nicht spezifiziert, da verschiedene Allocatoren es möglicherweise auf unterschiedliche Weise für Effizienzzwecke speichern möchten.

Es ist sinnvoll, wie zum Beispiel die Größe des zugewiesenen Blocks möglicherweise nicht unbedingt die gleiche Größe wie das Array. Während es ist wahr das new[] Kann die Anzahl der Elemente speichern (die einzelnen Elemente Destruktors anrufen), muss es nicht, da es für einen leeren Destruktor nicht erforderlich wäre. Es gibt auch keinen Standardweg (C ++ FAQ Lite 1, C ++ FAQ Lite 2) der Implementierung wo new[] Speichert die Arraylänge, da jede Methode ihre Vor- und Nachteile hat.

Mit anderen Worten, es ermöglicht Zuweisungen so schnell wie möglich, indem Sie nichts über die Implementierung angeben. (Wenn die Implementierung die Größe des Arrays sowie die Größe des zugewiesenen Blocks jedes Mal speichern muss, verschwendet sie den Speicher, den Sie möglicherweise nicht benötigen.)

Einfach ausgedrückt, erfordert der C ++ - Standard keine Unterstützung dafür. Wenn Sie genug über die Interna Ihres Compiler wissen, können Sie herausfinden, wie Sie auf diese Informationen zugreifen können, aber das würde dies tun allgemein als schlechte Praxis sein. Beachten Sie, dass es möglicherweise einen Unterschied im Speicherlayout für heap-zuallozierte Arrays und stapelgestützte Arrays gibt.

Denken Sie daran, dass im Wesentlichen auch das, worüber Sie hier sprechen, auch Arrays im C-Stil sind-obwohl Sie-obwohl new und delete sind C ++ - Operatoren - und das Verhalten wird von C geerbt. Wenn Sie ein C ++ - Array "Array" haben möchten, sollten Sie die STL verwenden (z. B. std :: vector, std :: deque).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top