2010-12-03 27 views
3

Je viens de commencer ma classe de conteneurs et déjà je suis: questions ayanterreur dans la classe destructor

class Container 
{ 
    private: 

    string* BasePointer; // The starting pointer. 
    unsigned int Capacity; // The number of values the container can hold. 

    public: 

    Container() // Default constructor. 
    { 
     Capacity = 1; 
     BasePointer = new string[Capacity]; 
    } 

    ~Container() // Destructor. 
    { 
     delete BasePointer; // Delete the container to prevent memory leaking. 
    } 
}; 

Je reçois l'erreur Container Classes(26467) malloc: *** error for object 0x100100088: pointer being freed was not allocated. Que fais-je incorrectement?

+1

Il est appelé * destructor *, comme dans la destruction. Pas déconstructeur. :) – jalf

+0

@jalf Droit, désolé. – Maxpm

Répondre

7

Le XXX ptr = new XXX[size] doit être mis en correspondance avec la version de groupe delete [] ptr, et pas seulement delete.

Lisez à propos de free store management en C++, et comme nous le rappelle James - suivez les rule of three dans des cas comme celui-ci.

+0

exactement à quoi je pensais –

+0

Merci. Y a-t-il une raison syntaxique pour le '[]'? Peut-il contenir un argument optionnel ou quelque chose? – Maxpm

+1

Non, vous ne devez pas fournir d'argument. Et la raison est - bien, ce qu'il fait est différent de ce que fait delete, donc il a besoin d'un nom différent;) – etarion

4

vous devez utiliser supprimer []

delete[] BasePointer; 
1

Salut si vous créez ensemble, vous devez utiliser supprimer [] BasePointer;

0

Pour être plus explicite que les autres - lorsque vous new -ed un type de tableau, vous devez supprimer le pointeur en utilisant delete[].

Cela ne se produit pas seulement lorsque vous utilisez new T[size], considérez l'exemple suivant:

typedef int T[42]; 
int* x = new T; 
delete[] x; // needs delete[] though you used new without [] 

Sur une note générale, si votre objet « possède » un objet qu'elle détient par l'intermédiaire d'un pointeur, vous devriez envisager d'utiliser un pointeur intelligent (comme boost :: scoped_array) pour cela. De cette façon, vous n'avez pas à vous soucier de la déconstruction, ce qui se passe quand une exception est jeté, la mise en œuvre op d'affectation et constructeur de copie ...

2

D'autres ont mentionné que vous avez new[] avec delete et ne correspondent pas, vous devez changer delete pour delete[] pour le réparer. Cependant, ce n'est que le premier de vos problèmes.

Vous devez également implémenter (ou au moins déclarer comme privé) le constructeur de copie et l'opérateur d'affectation de copie. Sinon, pensez à ce qui se passe quand vous faites ceci:

{ 
    Container c1; 
    Container c2(c1); 
} // c2.~Container(); // frees the memory pointed to by 'BasePointer' 
    // c1.~Container(); // also frees the memory pointed to by 'BasePointer'. 

Depuis le membre BasePointer des deux c1 et c2 des points au même tableau, il se libère deux fois.

Il existe des alternatives plus faciles à utiliser:

  • Pensez à utiliser un std::vector où vous pourriez utiliser autrement un tableau alloué dynamiquement. Puisque votre classe est appelée Container, je suppose que vous essayez d'implémenter un conteneur propriétaire de ressources, donc peut-être que vous ne voulez pas l'utiliser. Envisagez d'utiliser un boost::scoped_ptr ou std::unique_ptr (si votre compilateur le prend en charge) pour gérer la propriété du pointeur. Ces deux méthodes suppriment la génération du constructeur de copie implicitement déclaré, ce qui vous oblige à implémenter le vôtre si vous tentez réellement de les utiliser.

Même si vous implémentez un Container, vous devriez toujours profiter des conteneurs plus primitifs pour faire le levage de charges lourdes pour vous (ou, au moins réimplémenter ces conteneurs primitifs de sorte que le levage de charges lourdes est consolidée dans une petite ensemble d'utilitaires). Enfin, en tant que point stylistique, vous n'avez pas besoin d'utiliser malloc pour un conteneur. La bibliothèque standard fournit std::allocator qui peut être utilisé pour allouer de l'espace et construire des objets.