boost::shared_ptr kommt nicht mit unvollständigem Typ pcap_t zurecht
-
Ich benutze die pcap-Library und in dieser wird die pcap_t* Struktur nur mit forward declaration erstellt. Aber ich möchte gerne trotzdem einen SmartPointer zur verwalten nehmen. Wie lässt sich das lösen?
Beispiel:
#include <boost/shared_ptr.hpp> #include <pcap.h> void PcapClose(pcap_t* h) { if(h) { pcap_close(h); } } boost::shared_ptr<pcap_t> handle((pcap_t*)0, PcapClose); int main() { handle.reset((pcap_t*)0); // In Wirklich wird natürlich mit einem richtigen Wert initialisiert }/usr/include/boost/checked_delete.hpp: In function »void boost::checked_delete(T*) [with T = pcap_t]«: /usr/include/boost/detail/shared_count.hpp:86: instantiated from »boost::detail::shared_count::shared_count(Y*) [with Y = pcap_t]« /usr/include/boost/shared_ptr.hpp:124: instantiated from »boost::shared_ptr<T>::shared_ptr(Y*) [with Y = pcap_t, T = pcap]« /usr/include/boost/shared_ptr.hpp:237: instantiated from »void boost::shared_ptr<T>::reset(Y*) [with Y = pcap_t, T = pcap]« test2.cpp:16: instantiated from here /usr/include/boost/checked_delete.hpp:32: Fehler: Ungültige Anwendung von »sizeof« auf unvollständigen Typen »pcap_t« /usr/include/boost/checked_delete.hpp:32: Fehler: Feld negativer Größe (»-0x00000000000000001«) wird erzeugt /usr/include/boost/checked_delete.hpp:33: Fehler: Ungültige Anwendung von »sizeof« auf unvollständigen Typen »pcap_t« /usr/include/boost/checked_delete.hpp:33: Fehler: Feld negativer Größe (»-0x00000000000000001«) wird erzeugt /usr/include/boost/checked_delete.hpp:34: Warnung: mögliches Problem bei Aufruf des »delete«-Operators erkannt /usr/include/boost/checked_delete.hpp:29: Warnung: »x« has incomplete type /usr/include/pcap.h:65: Warnung: forward declaration of »struct pcap« /usr/include/boost/checked_delete.hpp:34: Anmerkung: weder der Destruktor noch der klassenspezifische Operator »delete« wird aufgerufen, auch wenn sie bei der Klassendefinition deklariert werdenmfg.
-
Dann mach doch einen vollständigen Typ draus (shared_ptr benötigt vermutlich irgendwo im Inneren die Größe des Zieltyps).
-
Der normale Deleter eines shared_ptr<T> benutzt delete p. Zwar muss dafür T an sich nicht vollständig sein, allerdings führt dies zu undefiniertem Verhalten, wenn T keinen trivialen Destruktor hat oder operator delete überlädt (ok, in letzterem Falle ist es nicht undefiniert, nur unerwünscht). Aus diesem Grunde existiert boost::checked_delete - der darin enthaltene sizeof-Ausdruck dient lediglich dazu, sicherzustellen, dass T ein vollständiger Typ ist und sonst einen Fehler beim Compilieren zu produzieren. Du kannst shared_ptr mit unvollständigem pcap_t verwenden, musst dabei aber peinlich darauf achten, stets deinen eigenen Deleter mitzugeben. Das ist hier nicht der Fall; auch reset verändert den Deleter
alsoint main() { handle.reset((pcap_t*)0, PcapClose); }sollte das gewünschte Ergebnis produzieren.