2016-06-10 6 views
-1

Löschen des Doppelzeigers ist der schädliche Effekt wie Absturz des Programms und Programmierer sollte versuchen, dies zu vermeiden, wie es nicht erlaubt ist. Aber irgendwann, wenn jemand das tut, dann wie kümmern wir uns darum. Als Löschen in C++ ist kein execept Operator und es werden keine Ausnahmen ausgelöst. Und sein schriftlicher Typ ist auch ungültig. Wie fangen wir diese Art von Ausnahmen? Unten ist der Code-SnippetWie man doppelt freien Absturz in C++ behandelt

class myException: public std::runtime_error 
{ 
    public: 
     myException(std::string const& msg): 
      std::runtime_error(msg) 
     { 
      cout<<"inside class \n"; 
      } 
}; 

void main() 
{ 

int* set = new int[100]; 
cout <<"memory allcated \n"; 
//use set[] 
delete [] set; 

cout <<"After delete first \n"; 
try{ 
delete [] set; 
throw myException("Error while deleting data \n"); 
} 
catch(std::exception &e) 
{ 
    cout<<"exception \n"; 
} 
catch(...) 
{ 
    cout<<"generic catch \n"; 
} 

cout <<"After delete second \n"; 

In diesem Fall habe ich versucht, die Ausnahme, aber keinen Erfolg zu fangen. Bitte geben Sie Ihre Eingabe, wie wir uns um diese Art von Szenario kümmern werden. danke im voraus !!!

+1

Verwenden Sie einen 'std :: vector'? –

+1

Es gibt * nichts *, was Sie in der C++ - Sprache tun können, um doppelte Löschungen zu verarbeiten. Es ist undefiniertes Verhalten; Der Standard "enthält keine Anforderungen". Wenn Sie doppelt löschen, stürzt Ihr Code möglicherweise ab (keine Ausnahme), formatieren Sie Ihre Festplatte oder stellen Sie Ihren Browser-Passwort-Cache auf github. –

Antwort

2

Da das Verhalten bei einem nachfolgenden delete[] ist undefined, gibt es nichts, was man tun kann, abgesehen von

set = nullptr;

unmittelbar nach dem ersten delete[] zu schreiben. Dies nutzt die Tatsache, dass eine Löschung eines nullptr ein No-Op ist.

Aber wirklich, das ermutigt nur Programmierer, schlampig zu sein.

1

Segmentierungsfehler oder schlechter Speicherzugriff oder Busfehler können nicht von der Ausnahme abgefangen werden. Programmierer müssen ihren eigenen Speicher korrekt verwalten, da Sie in C/C++ keine Speicherbereinigung haben.

Aber Sie verwenden C++, nein? Warum nicht RAII nutzen?
Hier ist, was sollten Sie tun streben:

  1. Eigentum Speicher - Explizit über den Einsatz von std::unique_ptr oder std::shared_ptr und Familie.
  2. Keine expliziten Raw-Aufrufe an new oder delete. Verwenden Sie make_unique oder make_shared oder allocate_shared.
  3. Verwenden Sie Container wie std::vector oder , anstatt dynamische Arrays zu erstellen oder Array auf Stack zuzuordnen.
  4. Führen Sie Ihren Code über Valgrind (Memcheck), um sicherzustellen, dass keine Speicherprobleme in Ihrem Code sind.

Wenn Sie shared_ptr verwenden, können Sie ein weak_ptr verwenden, um Zugriff auf die zugrunde liegenden Zeiger zu erhalten, ohne die Zählung Referenz erhöht wird. Wenn in diesem Fall der zugrunde liegende Zeiger bereits gelöscht ist, wird die Ausnahme bad_weak_ptr ausgelöst. Dies ist das einzige Szenario, das mir bekannt ist, wenn beim Zugriff auf einen gelöschten Zeiger eine Ausnahme ausgelöst wird.

Ein Code muss mehrere Stufen von Testing-Iterationen durchlaufen, möglicherweise mit verschiedenen Werkzeugsätzen, bevor er festgeschrieben wird.

+0

können wir den Segmentierungsfehler mit SIGSEGV .... plz fangen unter dem folgenden Link: http://StackOverflow.com/Questions/10202941/Segmentation-Fault-Handling –

+0

Das ist anders, Fangsignal ist nicht das gleiche wie eine Ausnahme zu fangen. Lass es mich neu formulieren. Vielen Dank. Der Signalhandler und der Ausnahmebehandler haben eine völlig andere Aufrufsemantik. – Arunmu

+0

so gibt es keine Möglichkeit, dass wir einen solchen Programmierfehler bekommen, jeder Programmierer muss auf seine eigene Ebene achten. –

1

Es gibt ein sehr wichtiges Konzept in C++ namens RAII (Resource Acquisition Is Initialization).

Dieses Konzept kapselt die Idee, dass kein Objekt existieren darf, es sei denn, es ist vollständig wartungsfähig und intern konsistent, und das Löschen des Objekts wird alle Ressourcen freigeben, die es enthielt.

Aus diesem Grunde wird, wenn das Zuweisen von Speicher verwenden wir intelligente Zeiger:

#include <memory> 
#include <iostream> 
#include <algorithm> 
#include <iterator> 

int main() 
{ 
    using namespace std; 

    // allocate an array into a smart pointer 
    auto set = std::make_unique<int[]>(100); 
    cout <<"memory allocated \n"; 

    //use set[] 
    for (int i = 0 ; i < 100 ; ++i) { 
     set[i] = i * 2; 
    } 

    std::copy(&set[0], &set[100] , std::ostream_iterator<int>(cout, ", ")); 
    cout << std::endl; 

    // delete the set 
    set.reset(); 

    cout <<"After delete first \n"; 

    // delete the set again 
    set.reset(); 
    cout <<"After delete second \n"; 

    // set also deleted here through RAII 
} 
0

mir eine andere Antwort hier hinzugefügt, weil frühere Antworten auf sehr stark konzentrieren manuell, dass der Speicher verwalten, während die richtige Antwort zu vermeiden, ist mit damit umzugehen.

void main() { 
    std::vector<int> set (100); 
    cout << "memory allocated\n"; 
    //use set 
} 

Das ist es. Das ist genug. Dies gibt Ihnen 100 Ganzzahlen, die Sie verwenden können, wie Sie möchten. Sie werden automatisch freigegeben, wenn der Kontrollfluss die Funktion verlässt, sei es durch eine Ausnahme oder eine Rückgabe oder durch das Abfallen vom Ende der Funktion. Es gibt kein doppeltes Löschen; Es gibt nicht einmal eine einzige Löschung, die so ist, wie es sein sollte.

Ich bin auch entsetzt, Vorschläge in anderen Antworten für die Verwendung von Signalen zu sehen, um die Auswirkungen dessen, was ein defektes Programm ist, zu verbergen. Wenn jemand genug von einem Anfänger ist, um dieses ziemlich grundlegende Zeug nicht zu verstehen, BITTE senden Sie sie nicht diesen Pfad hinunter.

+0

Ich sehe hier keine Antwort, die vorschlägt, Signalhandler zu verwenden. Beziehen Sie sich auf eine andere Antwort auf eine andere Frage? – Arunmu

+0

@Arunmu Es ist im ersten Kommentar unter Ihrer eigenen Antwort. Du hast darauf geantwortet. –

+0

'Vorschläge in anderen Antworten' das verwirrte mich :)' Kommentare _under_ andere Antworten' wäre weniger verwirrend gewesen. Entschuldigung für den Nissen. Ich bin auch kein englischer Muttersprachler. – Arunmu