Wie funktioniert löschen differenzierbare zwischen eingebauten Datentypen und Benutzer diejenigen definiert?

StackOverflow https://stackoverflow.com/questions/2347823

Frage

Wenn ich dies tun:

// (1.)
int* p = new int;
//...do something
delete p;

// (2.)
class sample
{
public:
sample(){}
~sample(){}
};
sample* pObj = new sample;
//...do something
delete pObj;

Dann wie funktioniert C ++ Compiler weiß, dass das Objekt folgender delete ist eingebauter Datentyp oder ein Klassenobjekt?

Meine andere Frage ist, dass, wenn ich einen Zeiger auf ein Array von new des int und dann delete [] ich dann wie funktioniert Compiler die Größe des Speicherblocks kennen zu de-zuteilen?

War es hilfreich?

Lösung

  1. Der Compiler kennt den Typ des spitzen-to-Objekt, weil es die Art des Zeigers kennt:

    • p ist ein int*, daher der Spitz-zu-Objekt wird ein int sein.
    • pObj ist ein sample*, daher der Spitz-zu-Objekt wird ein sample sein.
  2. Der Compiler nicht wissen, ob Ihre int* p Punkte zu einem einzigen int Objekt oder auf ein Array (int[N]). Deshalb Sie zu verwenden delete[] erinnern müssen statt delete für Arrays.

    Die Größe des Speicherblocks de-Zuweisung und, was am wichtigsten ist, die Anzahl der Objekte zu zerstören, bekannt sind, weil new[] speichert sie irgendwo, und delete[] weiß, wo diese Werte abzurufen. Diese Frage von C ++ FAQ Lite zeigt zwei gemeinsame Techniken new[] und delete[].

  3. implementieren

Andere Tipps

Es kennt den Unterschied zwischen ihnen wegen der Art des Zeigers Sie es passieren: Es ist das Verhalten nicht definiert einen anderen Zeigertyp passieren, als Sie mit zugewiesen (außer Sie einen Zeiger auf eine Basisklasse passieren können, wenn der destructor virtual, natürlich ist).

Die Größe eines Arrays wird irgendwo gespeichert werden. Es ist wie in C, wo Sie eine bestimmte Menge an Speicher malloc kann und frei danach - die Laufzeit zuvor die Größe zugewiesen verwalten müssen wissen.

Zum Beispiel kann es die Anzahl der Elemente speichert vor dem zugewiesenen Puffer. Der Standard ermöglicht explizit die Compiler eine unterschiedliche Anforderungsgröße auf die Zuteilungsfunktion (operator new[]) im Fall von Arrays Zuteilungen passieren - das von dem Compiler verwendet werden, um die Zählung zu kleben, und Offset die Adresse durch die new Expression durch die Größe zurück dieser Zähler.

Es ist nicht!

Alles etwas delete tut, ist, dass es den destructor des Typs aufruft, die „keine Aktion“ im Fall von primitiven Typen ist. Dann geht es um den Zeiger zu ::operator delete (oder eine überladene Version, wenn Sie mögen), und das ist Operator kehrt zurück, um den Speicher (ein Speichermanager Ausgabe). das heißt Sie können Ihre eigenen Speicher-Manager leicht in C ++ schreiben, wenn Sie möchten, stellt die Sprache ein standardmäßig!

  1. Der Compiler kennt die Art des Objekts gelöscht und anderen Code schreibt für Sie die richtigen Ergebnisse zu erzielen:
    • delete p kann die Laufzeit mit der Größe eines int löschen aufrufen.
    • Löschen pObj können anrufen pObj-> ~ Probe () zuerst, dann mit der Größe der Probe löschen
  2. Ich denke, mit Arrays, gibt es einen versteckten Wert für die Größe des Arrays, so ist es, dass die ganze Anordnung wird in einem Rutsch gelöscht werden kann.
  

Dann wie funktioniert C ++ Compiler weiß das Objekt folgende löschen ist eingebauter Datentyp oder ein Klassenobjekt?

Da der Compiler bei der Kompilierung verfolgt die Typen der einzelnen Objekte und Pflanzen des appropraite Code.

  

Meine andere Frage ist, dass, wenn ich neue ein Zeiger auf ein Array von int ist und dann [I delete] dann wie funktioniert die Größe des Speicherblocks Compiler kennen de-zuteilen?

Es ist nicht. Dies wird immer den Überblick über das Laufzeitsystem.
Wenn Sie dynamisch ein Array der Laufzeitbibliothek Mitarbeitern die Größe des Objekts zuweisen somit mit dem Objekt, wenn es löscht sie es weiß (mit dem zugehörigen Wert aufzublicken), um die Größe.

Aber ich denke, Sie wollen wissen, wie es den Verein tut?
Dies hängt von dem System und ist eine Implementierung Detail. Aber eine einfache stratergy ist eine zusätzliche 4 Bytes speichern die Größe in den ersten vier Bytes zugewiesen werden dann zugeordnet einen Zeiger auf das 4. Byte zurück. Wenn Sie einen Zeiger löschen wissen Sie, dass die Größe die 4 Bytes vor dem Zeiger ist. . Hinweis: Ich sage nicht, Ihr System diese Technik verwendet, aber es ist ein stratergy

Für den ersten (nicht-Array) ist Teil der Frage, die Antworten über das anzeigt, dass der Code Compiler fügt die entsprechende Anzahl von Bytes auf dem Zeigertyp basiert auf De-zuweisen, bieten keine ganz klare Antwort für mich ... der delete-Operator 1) ruft eine destructor falls zutreffend und dann 2) ruft den "Operator delete ()" Funktion ... es Betreiber, die tatsächlich de-zuordnet wird löschen. Ich kann Compiler generierte Code eine Rolle spielen, in Teil (1), dh sehen. die Zieladresse des destructor muss eingefügt werden. Aber in Teil (2), ist es eine bereits bestehende Bibliotheksfunktion, die de-Zuordnung Handhabung, so wie wird es die Größe der Daten wissen? Der globale Betreiber löscht - die, wie ich glaube, in allen Fällen verwendet wird, es wäre denn, eine Klasse-Mitglied / überlastet-globale Version vom Programmierer definiert ist - akzeptiert nur ein void * Argument spec'ing den Starts der Daten, so kann es ‚t sogar die Datengröße übergeben werden. Ich habe gelesen, was den Compiler generierten Code Idee angibt, sowie Dinge, was darauf hindeutet, dass der globale Operator für Nicht-Arrays löschen Sie einfach frei verwendet (), dh. sie kennt die Datengröße nicht vom Zeigertyp, aber durch ein paar Bytes, bevor die Daten suchen selbst, wo die Größe von neuem / Malloc gebunkert worden sein. Letztere ist die einzige Lösung, die für mich Sinn macht, aber vielleicht kann mir jemand anders aufklären ...

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