Question

est ma fonction addCard qui prend une carte à jouer en tant que paramètre puis mains sur l'adresse de son auto à un tableau attribué de pointeurs vers des objets carte à jouer.

void cardHand::addCard(playingCard card) {
    theHand[nElems++] = &card;
} // addCard()

maintenant, quand je lance mon programme, il fonctionne très bien mais tombe en panne lorsque le destructeur.

cardHand::~cardHand() {
    for(int c = 0;c<MAX;c++) {
        if(theHand[c] != NULL)
            delete theHand[c]; // here is the problem
    }
    delete [] theHand;
} // class destructor

est-ce plantage parce que je suis seulement la remise de l'adresse de l'objet dans la fonction carte à jouer addCard. devrait-il être un pointeur à la place?

Était-ce utile?

La solution

Le problème est ici

void cardHand::addCard(playingCard card) { theHand[nElems++] = &card; }

Vous pouvez stocker l'adresse de l'objet carte temporaire qui sera détruite à la fin de la méthode addCard.

Et dans votre destructor vous essayez de le supprimer à nouveau.

Vous avez deux options.

Première :. AddCard faire accepter simplement la configuration de la carte et créez votre carte avec new dans la méthode addCard
Deuxième : accepter la carte par pointeur mais la destructor de votre cardHand ne peut pas être responsable de la suppression de la carte. Et la suppression interprétera objet de plate-forme qui a créé toutes les cartes.

Autres conseils

Quand vous dites:

theHand[nElems++] = &card;

Vous mémoriser l'adresse d'un paramètre de fonction, qui est effectivement une variable locale. C'est toujours une mauvaise chose à faire, et dans votre cas provoque l'accident lorsque vous essayez de le supprimer.

Vous voulez probablement quelque chose comme:

theHand[nElems++] = new playingcCard( card );

mais la vraie solution est d'utiliser un std :: vecteur et carte à jouer en finir avec l'allocation dynamique tout à fait.

Vous utilisez C ++ comme un meilleur C, et bien que cela soit bien à de nombreuses fins, il n'est pas idiomatiques C ++.

Qu'est-ce que vous voulez vraiment est de supprimer l'allocation dynamique tout à fait. En général, si vous écrivez C ++, vous devez utiliser très rarement new et utiliser encore plus rarement delete.

Votre main doit être déclaré quelque chose comme ceci:

std::vector< playingCard > hand;

Les nouvelles cartes devraient être mis dessus avec quelque chose comme ceci:

hand.push_back( card );

Vous devriez trouver que, en utilisant les classes de collection de la bibliothèque C ++ (et les smart TR1 pointes) vous ne devez jamais utiliser new ou delete -. Jusqu'à ce que vous arriviez à écrire vos propres pointeurs intelligents de toute façon

Alors, étant donné les autres réponses, ma façon de le faire serait la main sur une référence ou un pointeur vers un playingCard.

Et en ce qui concerne delete, la règle générale est, vous ne delete ce que vous newed, à savoir celui qui alloue la mémoire doit être responsable de son disposale. Bien sûr, comme toute règle, il y a des exceptions à cela, mais ce comportement doit être très bien documenté dans le contrat d'une interface.

Il se bloque sur delete parce qu'il n'a jamais été attribué à new.

void cardHand::addCard(playingCard card) {
    theHand[nElems++] = &card;
} // addCard()

Dans cet appel de fonction, vous passez une copie temporaire de la carte à jouer et de prendre son adresse. Le stockage des adresses de est un non temporaires, pas à moins que vous savez vraiment ce que vous faites.

Au lieu de cela, changer cela à quelque chose comme

/** @param card card to add. Takes ownership. */
void cardHand::addCard(playingCard *card) {
    theHand[nElems++] = card;
} // addCard()

Et dans le code d'appel, passer un pointeur d'objet playingCard retour de new playingCard.

Il a encore la question du transfert de propriété d'objet une raison commune pour le double supprimer des bugs ou des fuites de mémoire. Il est une bonne habitude de faire de tels transferts explicites avec des commentaires de code.

Règle de base: Ne supprimez ce que vous avez alloué (soit avec une nouvelle ou avec malloc)

Par conséquent, votre accident.

La raison pour laquelle il ne fonctionne pas est que vous passez votre classe par valeur cardHand::addCard.
Alors, que le compilateur n'est construit une copie temporaire de votre instance de classe sur la pile.
Comme il est sur la pile, il se nettoyer automatiquement une fois le retour de la fonction addCard.
Vous pouvez corriger cela en passant votre instance playingCard comme pointeur à la place.
Cependant, comme d'autres dans ce poste ont dit, il est conseillé de ne pas delete choses que vous ne l'avez pas new explicitement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top