Verhalten von malloc mit delete in C++

Lesezeit: 4 Minuten

Benutzer-Avatar
Liebling

int *p=(int * )malloc(sizeof(int));

delete p;

Wenn wir Speicher mit malloc zuweisen, sollten wir ihn mit free freigeben, und wenn wir mit new in C++ zuweisen, sollten wir ihn mit delete freigeben.

Aber wenn wir Speicher mit malloc zuweisen und dann delete verwenden, sollte es einen Fehler geben. Aber im obigen Code gibt es keinen Fehler oder keine Warnung in C++.

Auch wenn wir umkehren und mit new zuweisen und mit free freigeben, gibt es auch keinen Fehler oder keine Warnung.

Wieso ist es so?

  • Denken Sie auch an Konstruktoren und Destruktoren.

    – Jaywalker

    1. Juni 2012 um 16:39 Uhr

  • Es gibt vielleicht keine Warnung, aber es ist definitiv ein Fehler. (So ​​oder so)

    – CB Bailey

    1. Juni 2012 um 16:40 Uhr


  • da sollte ein fehler vorliegen” – sagt wer? Das Verhalten ist undefiniert und der C++-Standard gibt keinen Kommentar dazu ab, was passieren soll. Wenn Sie einen Fehler wollen, müssen Sie möglicherweise ein anderes Tool verwenden, z Valgrind.

    – Robᵩ

    1. Juni 2012 um 16:41 Uhr


Dies ist ein undefiniertes Verhalten, da es keine Möglichkeit gibt, zuverlässig zu beweisen, dass der Speicher hinter dem Zeiger korrekt zugewiesen wurde (dh durch new zum delete oder new[] zum delete[]). Es ist Ihre Aufgabe, dafür zu sorgen, dass so etwas nicht passiert. Es ist einfach, wenn Sie die richtigen Werkzeuge verwenden, nämlich intelligente Zeiger. Wann immer du sagst deleteDu machst es falsch.

  • Grundsätzlich sagt der C++-Standard, dass wenn Sie mit zuweisen malloc und frei mit delete, können Sie einen Atomschlag starten. Du willst nicht, dass das passiert, oder? Nun, seien wir realistisch: Wenn Sie darauf bestehen, zahlen Sie Monate oder Jahre später dafür, 3 Tage bevor Sie in den Familienurlaub fahren, und Sie verbringen 48 Stunden damit, das Problem herauszufinden. Das bedeutet undefiniertes Verhalten in der Praxis. Schlaflose Nächte.

    – Kuba hat Monica nicht vergessen

    1. Juni 2012 um 20:07 Uhr

  • Whoa whoa whoa, ich war bis zu deinem letzten Satz bei dir, und ich wie intelligente Hinweise. Sie sind jedoch nicht immer ein geeigneter Ersatz für new/delete (was zum Beispiel, wenn Sie Ihre eigene Smart-Pointer-Klasse schreiben und auf einem eingebetteten Computer ohne Standardbibliothek bereitstellen? Was ist, wenn Sie nicht weiterkommen? mit einem alten Compiler, der nur auto_ptr als Smart Pointer bereitstellt?), daher ist es unnötig zu sagen, dass die Verwendung von delete “falsch macht” (auch wenn es stimmt, dass Smart Pointer normalerweise ein besserer Ansatz sind).

    – Kyle Strand

    14. November 2015 um 15:40 Uhr

  • Eigentlich immer noch ist es falsch machen. Das solltest du nicht delete direkt in Ihrem intelligenten Zeiger, sollten Sie stattdessen ein Funktionsobjekt (entweder als Vorlage oder als gelöschten Typ) nehmen und dieses verwenden, um das Objekt zu löschen. Das einzige Löschen, das beim Hinzufügen von Smart Pointern erforderlich ist, ist in std::default_deleter.

    – Welpe

    14. November 2015 um 20:33 Uhr


  • @KyleStrand Ugh, diese dummen Argumente tauchen immer wieder auf. Wenn Sie Ihre eigene Smart-Pointer-Klasse schreiben oder eingebettete Software schreiben, fragen Sie sich nicht, ob Sie malloc und delete mischen können. Falsches Publikum. Abgesehen davon ist die Anzahl der Fälle, in denen Sie Ihren eigenen intelligenten Zeiger schreiben würden, nahe 0, da unique_ptr für fast alles generisch genug ist (und diese anderen Fälle sind entweder shared_ptr oder deep-cloning value_ptr und all das ist sowieso bereits geschrieben). Und wenn Sie mit einem über 5 Jahre alten Compiler stecken bleiben jemandes sicher falsch machen (auch Boost).

    – Katze Plus Plus

    14. November 2015 um 20:34 Uhr

  • @CatPlusPlus In diesem Fall klingt es so, als ob Sie wirklich meinten, “wenn Anfänger verwenden deletesie machen es falsch” – was wohl wahr ist, aber was Sie gesagt haben, war viel breiter als das. Was über 5 Jahre alte Compiler betrifft, so arbeite ich für ein Unternehmen, das sich derzeit im Post-Release-Support für mehrere eingebettete Systeme befindet, die mit MSVC 2008 (und in einem Fall 2003) programmiert wurden und auf XP Embedded und Windows Embedded Standard 2009 abzielen, und sie einfach haben weder die Manpower, um die Codebasis im Rahmen ihrer laufenden Wartungsbemühungen nach vorne zu portieren, noch gibt es einen dringenden Grund dafür.

    – Kyle Strand

    14. November 2015 um 22:47 Uhr

dann sollte da ein fehler sein

Es gibt. Es ist nur nicht unbedingt ersichtlich.

Der C++-Standard (und der C-Standard, der dem C++-Standard nachempfunden ist) nennt diese Art von Fehler undefiniertes Verhalten. Von nicht definiert sie bedeuten, dass überhaupt alles passieren kann. Das Programm kann normal fortgesetzt werden, es kann sofort abstürzen, es kann eine wohldefinierte Fehlermeldung erzeugen und ordnungsgemäß beendet werden, es kann einige Zeit nach dem eigentlichen undefinierten Verhaltensereignis anfangen, zufällige Fehler zu zeigen, oder nasale Dämonen beschwören.

Es liegt in Ihrer Verantwortung, diese Fehler zu beobachten und zu beseitigen. Nichts wird Sie garantiert benachrichtigen, wenn sie passieren.

  • Ich stimme zu, dass dies UB ist, aber ich hätte gerne einen Standardverweis, wo es so steht, bitte 🙂

    – Emily L.

    13. August 2013 um 10:40 Uhr

  • @EmilyL: Der C ++ – Standard befasst sich nicht speziell mit dem Mischen von Neu und Frei. Es heißt, Sie dürfen nur passieren, um zu löschen, was Sie von Neuem haben. Der C-Standard sagt ebenfalls über malloc und free.

    – n. 1.8e9-wo-ist-meine-Aktie m.

    13. August 2013 um 12:26 Uhr

Benutzer-Avatar
andre

Benutzen free() nicht delete.

wenn du malloc dann musst du anrufen free Speicher freizugeben.

wenn du new du musst anrufen delete Speicher freizugeben.

Hier ist ein Link, der es erklärt.

1013060cookie-checkVerhalten von malloc mit delete in C++

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

Privacy policy