Wie löscht[] “Kennen” Sie die Größe des Operanden-Arrays?

Lesezeit: 5 Minuten

Wie loscht Kennen Sie die Grose des Operanden Arrays
VolkerK

Foo* set = new Foo[100];
// ...
delete [] set;

Sie übergeben die Grenzen des Arrays nicht an delete[]. Aber wo werden diese Informationen gespeichert? Ist es standardisiert?

  • sourceforge.net/projects/fastmm ist Open Source und ersetzt den Memory-Manager. Hier erfahren Sie, wie die Speicherverwaltung funktioniert und woher die Informationen zum Zuordnen und Löschen von Speichern kommen.

    Benutzer5598651

    2. Februar 2016 um 15:46 Uhr

  • Beachten Sie, dass FastMM nur für die Delphi/C++Builder-Compiler spezifisch ist, es ist kein universeller Speichermanager für C++. Es ist nicht einmal in C++ geschrieben.

    – Rémy Lebeau

    26. Oktober 2016 um 23:18 Uhr

Wie loscht Kennen Sie die Grose des Operanden Arrays
Peter Kühn

Wenn Sie Speicher auf dem Heap zuweisen, verfolgt Ihr Zuordner, wie viel Speicher Sie zugewiesen haben. Dies wird normalerweise in einem “Kopf”-Segment direkt vor dem Speicher gespeichert, der Ihnen zugewiesen wird. Auf diese Weise weiß der De-Allocator genau, wie viel Speicher er freigeben muss, wenn es an der Zeit ist, den Speicher freizugeben.

  • Beachten Sie, dass dies nur für Arrayzuweisungen in C++ gilt. Alle anderen Zuordnungen hängen von der Größe des Typs ab. Einige Bibliotheken speichern alle Zuordnungsgrößen, normalerweise nur im Debugging-Modus.

    – Zan Luchs

    13. Oktober 2008 um 14:30 Uhr

  • Es gibt absolut keinen Grund, warum diese Informationen dem Programmierer nicht zur Verfügung stehen sollten. Ich kann einen Zeiger auf eine Funktion übergeben und sie freigeben, aber um die Größe selbst in derselben Funktion zu erhalten, muss ich einen zusätzlichen Parameter herumreichen. Macht das irgendeinen Sinn?

    – Markus Ruzon

    11. Juni 2009 um 0:16 Uhr

  • @Mark, es macht a klein sinnvoll, weil es den Zuordner theoretisch freigibt, immer die Größe von zu speichern zugeteilt Block (der von der Größe der angefordert Block). Bestimmte Zuweisungsentwürfe benötigen diese Informationen möglicherweise für ihre eigenen Zwecke oder sind möglicherweise nicht ausgefeilt genug, um Typinformationen zu verwenden, um die Größe von Nicht-Array-Heap-Zuweisungen usw. zu verfolgen. Den Zuordner zwingen, die angeforderte Größe zu speichern (damit Sie dies nicht tun würden müssen die Array-Größe selbst übergeben) könnte eine kleine Belastung sein, aber es könnte Auswirkungen auf die Leistung auf denkbare Allokator-Designs haben.

    – Doug McClean

    24. Oktober 2009 um 4:27 Uhr

  • Entschuldigung, aber diese Antwort verfehlt den Punkt. Was QuantumPete beschrieben hat, ist im Grunde „Wie free weiß, wie viel Speicher freigegeben werden muss”. Ja, die Speicherblockgröße wird “irgendwo” gespeichert malloc (normalerweise im Block selbst), also so free weiß. Aber, new[]/delete[] ist eine andere Geschichte. Letztere arbeiten grundsätzlich auf malloc/free. new[] speichert auch die Anzahl der erstellten Elemente im Speicherblock (unabhängig von malloc), also später delete[] kann diese Nummer abrufen und verwenden, um die richtige Anzahl von Destruktoren aufzurufen.

    – Ant

    24. Oktober 2009 um 4:35 Uhr

  • Dh physikalisch werden im Block zwei Zähler gespeichert: Blockgröße (by malloc) und Elementanzahl (by new[]). Beachten Sie, dass Ersteres nicht zur Berechnung von Letzterem verwendet werden kann, da die Größe des Speicherblocks im Allgemeinen größer sein kann, als für das Array der angeforderten Größe wirklich erforderlich ist. Beachten Sie auch, dass der Array-Element-Zähler nur für Typen mit nicht-trivialem Destruktor benötigt wird. Bei Typen mit trivialem Destruktor wird der Zähler nicht von gespeichert new[] und natürlich nicht von abgerufen delete[].

    – Ant

    24. Oktober 2009 um 4:38 Uhr

Wie loscht Kennen Sie die Grose des Operanden Arrays
Avt

EINER DER Ansätze für Compiler besteht darin, etwas mehr Speicher zuzuweisen und eine Anzahl von Elementen in einem Head-Element zu speichern.

Beispiel, wie es gemacht werden könnte:

Hier

int* i = new int[4];

Compiler wird zuweisen sizeof(int)*5 Byte.

int *temp = malloc(sizeof(int)*5)

Wird “4” in der ersten speichern sizeof(int) Byte

*temp = 4;

und einstellen i

i = temp + 1;

Damit i wird auf ein Array von 4 Elementen zeigen, nicht 5.

Und Löschen

delete[] i;

werden wie folgt verarbeitet:

int *temp = i - 1;
int numbers_of_element = *temp; // = 4
... call destructor for numbers_of_element elements
... that are stored in temp + 1, temp + 2, ... temp + 4 if needed
free (temp)

  • Kann dies geändert werden, um zur Laufzeit Array-Längen zu erhalten?

    – Jessie Lesben

    22. Dezember 2020 um 8:46 Uhr

  • Ja, wenn Sie UB missbrauchen wollen. Das könntest du zum Beispiel machen ptr[-1].

    Benutzer4945014

    17. September 2021 um 1:24 Uhr

Die Angaben sind nicht standardisiert. In den Plattformen, an denen ich gearbeitet habe, werden diese Informationen jedoch kurz vor dem ersten Element im Speicher gespeichert. Daher könnten Sie theoretisch darauf zugreifen und es inspizieren, aber es lohnt sich nicht.

Auch deshalb müssen Sie delete verwenden [] wenn Sie Speicher mit new zugewiesen haben []da die Array-Version von delete weiß, dass (und wo) sie suchen muss, um die richtige Menge an Speicher freizugeben – und die entsprechende Anzahl von Destruktoren für die Objekte aufzurufen.

1647151211 61 Wie loscht Kennen Sie die Grose des Operanden Arrays
MSN

Es ist im C++-Standard Compiler-spezifisch definiert. Was Compiler-Magie bedeutet. Es kann mit nicht-trivialen Ausrichtungsbeschränkungen auf mindestens einer großen Plattform brechen.

Sie können über mögliche Implementierungen nachdenken, indem Sie dies erkennen delete[] ist nur für Zeiger definiert, die von zurückgegeben werden new[]der möglicherweise nicht derselbe Zeiger ist, der von zurückgegeben wird operator new[]. Eine Implementierung in freier Wildbahn besteht darin, die Array-Anzahl im ersten von zurückgegebenen int zu speichern operator new[]und haben new[] gibt einen Zeiger-Offset darüber hinaus zurück. (Deshalb können nicht-triviale Ausrichtungen brechen new[].)

Denk daran, dass operator new[]/operator delete[]!=new[]/delete[].

Außerdem ist dies orthogonal dazu, wie C die Größe des zugewiesenen Speichers kennt malloc.

Grundsätzlich ist es im Speicher angeordnet als:

[info][mem you asked for…]

Wobei info die Struktur ist, die von Ihrem Compiler verwendet wird, um die zugewiesene Speichermenge zu speichern und was nicht.

Dies ist jedoch implementierungsabhängig.

1647151212 956 Wie loscht Kennen Sie die Grose des Operanden Arrays
jeffm

Dies ist nicht etwas, das in der Spezifikation steht – es ist implementierungsabhängig.

1647151212 919 Wie loscht Kennen Sie die Grose des Operanden Arrays
Joel Coehoorn

Denn das zu „löschende“ Array hätte mit einer einzigen Verwendung des „new“-Operators erstellt werden sollen. Die „neue“ Operation hätte diese Informationen auf den Haufen legen sollen. Wie würden sonst zusätzliche Verwendungen von new wissen, wo der Haufen endet?

996180cookie-checkWie löscht[] “Kennen” Sie die Größe des Operanden-Arrays?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy