2010-03-23 6 views
6

Was ist "minimaler Rahmen" (notwendige Methoden) von komplexen Objekt (mit explizit mallocated internen Daten), die ich in STL-Container, z. <vector>?Speichern von Objekten in STL-Vektor - minimale Menge von Methoden

Für meine Annahmen (zB von komplexen Objekt Doit):

#include <vector> 
#include <cstring> 
using namespace std; 
class Doit { 
    private: 
     char *a; 
    public: 
     Doit(){a=(char*)malloc(10);} 
     ~Doit(){free(a);} 
}; 

int main(){ 
    vector<Doit> v(10); 
} 

gibt

*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x0804b008 *** 
Aborted 

und in valgrind:

malloc/free: 2 allocs, 12 frees, 50 bytes allocated. 

UPDATE:

Minimal Methoden für solche obj ect sind: (basierend auf sbi Antwort)

class DoIt{ 
    private: 
     char *a; 
    public: 
     DoIt() { a=new char[10]; } 
     ~DoIt() { delete[] a; } 
     DoIt(const DoIt& rhs) { a=new char[10]; std::copy(rhs.a,rhs.a+10,a); } 
     DoIt& operator=(const DoIt& rhs) { DoIt tmp(rhs); swap(tmp); return *this;} 
     void swap(DoIt& rhs) { std::swap(a,rhs.a); } 
}; 

Danke, sbi, https://stackoverflow.com/users/140719/sbi

+0

Benötigen Sie einen Vergleich? –

+5

Sie sollten wirklich Vektoren von anstelle von Ihren eigenen mallocs verwenden. Das ist schließlich C++. – Joe

+0

nein. aber ich brauche wirklich einen Zeiger in einem Objekt, das malloced ist. – osgx

Antwort

10

Beachten Sie, dass Charles answered your question perfekt ist.

Wie auch immer, wie in der Rule of Three, sollte Ihre Klasse, die einen Destruktor hat, auch einen Kopierkonstruktor und einen Zuweisungsoperator haben.

Hier ist, wie ich es tun würde:

class Doit { 
    private: 
     char *a; 
    public: 
     Doit()     : a(new char[10]) {} 
     ~Doit()     {delete[] a;} 
     DoIt(const DoIt& rhs) : a(new char[10]) {std::copy(rhs.a,rhs.a+10,a);} 
     void swap(DoIt& rhs)  {std::swap(a,rhs.a);} 
     DoIt& operator=(DoIt rhs) {swap(rhs); return *this;} 
}; 
+0

Können Sie den Code des Kopierkonstruktors und den Zuweisungsoperator für meinen Fall angeben? – osgx

+0

@osgx: Ich habe den Code hinzugefügt. – sbi

+0

Ich denke, Sie fehlen ein Doppelpunkt nach dem Doit() - Konstruktor – AshleysBrain

0

Alle vector erfordert ist, dass das Objekt „zuordenbar“, was bedeutet, dass sie eine Kopie-Konstruktor, Destruktor muss und Zuweisungsoperator, die alle erzeugt werden Standardmäßig, wenn Sie sie nicht selbst liefern.

Wie sbi sagt, wenn Sie eine dieser Funktionen benötigen, dann brauchen Sie wahrscheinlich alle. In Ihrem Fall müssen Sie außerdem einen Kopierkonstruktor und einen Zuweisungsoperator bereitstellen, um eine Heap-Beschädigung zu vermeiden.

+0

kopierbar! = Zuweisbar. –

6

Alle Typen, die Sie verwenden, müssen CopyConstructible und Assignable sein.

CopyConstructible für einen Typ T bedeutet, dass wenn ein tT oder ein const T dann der Ausdruck T(t) muss eine äquivalente T zur ursprünglichen t erzeugen; t. ~ T() muss gültig sein (zugreifbarer Destruktor); und &t müssen die Adresse t als [const] T* angeben.

Assignable bedeutet, dass für ein T, t und ein T Wert u der Ausdruck t = ut entsprechen uT& und vom Typ sein, treffen müssen.

Beachten Sie, dass alle diese Anforderungen von einfachen integrierten Typen und POD-Strukturen erfüllt werden. Wenn Sie in einem Destruktor oder Konstruktor etwas nicht-triviales tun, müssen Sie sicherstellen, dass der Kopierkonstruktor und der Kopierzuweisungsoperator die Äquivalenzsemantik erhalten.

+1

Können Sie einen Link zur Tabelle angeben, welche Konzepte (Zuweisbar, CopyConstructible, andere?) Für verschiedene STL-Container (vector/map/priority_queue/hash/etc) erforderlich sind, um nicht-triviale Objekte in ihnen zu speichern. – osgx

+2

Sie sind nicht "Konzepte", sie sind Typ _requirements_ und Sie können sie in [dem Standard] finden (http://stackoverflow.com/questions/81656/where-do-i-find-the-current-c- oder-c-Standard-Dokumente). –

Verwandte Themen