Frage

Das Ignorieren Programmierstil und Design, ist es „sicher“ auf eine Variable auf dem Stapel zugeordnet löschen anrufen?

Zum Beispiel:

   int nAmount;
   delete &nAmount;

oder

class sample
{
public:
    sample();
    ~sample() { delete &nAmount;}
    int nAmount;
}
War es hilfreich?

Lösung

No , ist es nicht Safe delete auf einem Stapel zugewiesene Variable zu nennen. Sie sollten nur delete auf Dinge von new erstellt nennen.

  • Für jede malloc oder calloc, sollte es genau ein free.
  • Für jede new sollte es genau ein delete.
  • Für jede new[] sollte es genau ein delete[].
  • Für jeden Stapel Zuteilung sollte es keine explizite Freigabe oder Löschung sein. Der Destruktor wird automatisch aufgerufen, wo anwendbar.

In der Regel können Sie nicht davon mischen und anzupassen, z.B. kein free-ing oder delete[]-ing ein new Objekt. so ergibt sich ein undefiniertes Verhalten zu tun.

Andere Tipps

Nun, versuchen sie es:

jeremy@jeremy-desktop:~$ echo 'main() { int a; delete &a; }' > test.cpp
jeremy@jeremy-desktop:~$ g++ -o test test.cpp
jeremy@jeremy-desktop:~$ ./test
Segmentation fault

So offensichtlich ist es überhaupt nicht sicher.

Beachten Sie, dass, wenn Sie einen Speicherblock mit neuen (oder malloc was das betrifft) zuzuordnen, zugeordnet der tatsächliche Speicherblock wird größer sein als das, was Sie gefragt. Der Speicherblock wird auch einige Buchhaltungsinformationen enthalten, so dass, wenn Sie den Block freizugeben, kann es leicht wieder in den freien Pool gestellt werden und möglicherweise mit benachbarten freien Blöcken verschmolzen werden.

Wenn Sie versuchen, eine Erinnerung zu befreien, die Sie nicht von neuen erhalten haben, dass Buchhaltungsinformationen werden nicht dort sein, aber das System handeln, wie es ist, und die Ergebnisse werden unberechenbar (in der Regel schlecht) sein.

Ja, es ist nicht definiertes Verhalten: passing etwas delete, die nicht aus new gekommen ist UB:

  

C ++ Standard Abschnitt 3.7.3.2.3:   Der Wert des ersten Arguments einen der Thea Deallokation Funktionen in der Standardbibliothek bereitgestellt geliefert wird, kann ein null Zeigerwert sein; wenn ja, und wenn die Aufhebung der Zuordnung einer Funktion in der Standardbibliothek geliefert ist, hat der Aufruf an die Aufhebung der Zuordnung Funktion keine Auswirkung. Andernfalls wird der Wert zuzuführenden operator delete(void*) in der Standardbibliothek einen des Wertes von einem frühen Aufruf von entweder operator new(std::size_t) operator new(std::size_t, const std::nothrow_t&) oder in der Standardbibliothek zurückgeführt werden.

Die Folgen der undefinierten Verhalten sind, na ja, nicht definiert. „Nichts passiert“ ist als gültige Folge als irgendetwas anderes. Allerdings ist es in der Regel „nichts sofort geschieht“. Einen ungültigen Speicherblock freigibt, in späteren Aufrufen schwerwiegende Folgen auf das allocator hat

Nach einem wenig mit g ++ 4.4 in Windows zu spielen, habe ich sehr interessante Ergebnisse:

  1. Aufruf auf einem Stapel Variable löschen scheint nicht, etwas zu tun. Keine Fehler werfen, aber ich kann die Variable ohne Probleme nach dem Löschen zugreifen zu können.

  2. eine Klasse mit einer Methode mit delete this Nachdem erfolgreich löscht das Objekt, wenn es in dem Heap zugeordnet wird, aber nicht, wenn es in dem Stapel zugeordnet ist (wenn es in dem Stapel ist, passiert nichts).

Niemand kann wissen, was passiert. Das ruft nicht definiertes Verhalten, so buchstäblich alles passieren kann. Sie dies nicht tun.

Nein, Speicher mit neuen zugewiesen sollte löschen Verwendung gelöscht Operator und dass zugewiesen mit malloc sollte mit dem kostenlosen gelöscht werden. Und keine Notwendigkeit, die Variable freigeben, die auf Stapel zugeordnet sind.

Ein Engel verliert seine Flügel ... Sie nur delete auf einem Zeiger zugewiesen mit new aufrufen können, sonst Sie nicht definiertes Verhalten zu bekommen.

Hier wird der Speicher mit Stapeln so dass keine Notwendigkeit zugeordnet es exernally zu löschen, aber wenn Sie dynamisch allcoted

wie int * a = new int ()

, dann müssen Sie ein tun löschen und nicht löschen & a (a selbst ist ein Zeiger), da der Speicher aus freien Speicher zugeordnet ist.

Sie bereits beantwortet die Frage selbst. delete darf nur für Zeiger verwendet werden optained durch new. Etwas anderes zu tun ist schlicht und einfach nicht definiertes Verhalten.

Deshalb gibt es wirklich keine zu sagen, was passiert, etwas von dem Code adaequat zu Löschen einer Festplatte durch Absturz ist ein gültiges Ergebnis, dies zu tun. Also bitte dies nie tun .

Es ist UB, weil Sie nicht auf ein Element löschen aufrufen müssen, die mit neuen nicht dynamisch zugeordnet. Es ist so einfach.

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