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 werden
    

    mfg.



  • Dann mach doch einen vollständigen Typ draus (shared_ptr benötigt vermutlich irgendwo im Inneren die Größe des Zieltyps).


  • Mod

    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
    also

    int main()
    {
        handle.reset((pcap_t*)0, PcapClose);
    }
    

    sollte das gewünschte Ergebnis produzieren.


Anmelden zum Antworten