J'ai des fonctions (C ++) contenant chacune plusieurs appels créant des tableaux similaires du même type de base sur le tas. À différents moments de ces fonctions, j'ai peut-être besoin de jeter une exception. Garder une trace de laquelle des tableaux ont été supprimés est une douleur, et tout à fait un sujet d'erreur, alors je pensais simplement ajouter les pointeurs de tableau à un Set try
{
set<ArrType*> sHeap;
ArrType* myArr = new ArrType[5];
sHeap.Add(myArr);
someExternalRoutine(myArr);
...
}
catch(CString s)
{
DeleteAllPointersInMyHeap(sHeap);
throw(s);
}
5 Réponses :
Vous devez utiliser un Raii Techinque. Vous déléguez la destruction à un autre objet que vous créez sur la pile. P>
Puis, lorsque cet objet sort de la portée, il suffira de tout, peu importe quand il est hors de portée, même avec une exception. P>
Pourquoi ne pas utiliser un pointeur intelligent comme boost :: Shared_array code> ou utilisez une pile-alloué std :: vecteur code> ? Pour les allocations simples plutôt que des allocations de tableau, vous pouvez utiliser Boost :: partagé_ptr code> . P>
Celles-ci implémentent le Raii pour vous. Même si vous utilisez un concept comme Raii, vous réinventez toujours la roue s'il y a déjà une mise en œuvre concrète qui satisfait à vos exigences. P>
Vous n'avez pas à compter sur la collecte des ordures. P>
Vous avez STD :: AUTO_PTR qui fournit un pointeur comme la syntaxe et enveloppe un objet attribué dynamiquement. Lorsqu'il est détruit, il détruit automatiquement l'objet qu'il pointe. P>
Vous pouvez mettre en œuvre quelque chose de similaire pour les tableaux. P>
auto_ptr ne doit pas utiliser si le pointeur est à l'intérieur d'un conteneur STD, comme cela semble être le cas ici
@Neil, il n'est pas clair si l'OP aurait besoin de les mettre dans un conteneur STD s'il ne l'utilisait pas pour suivre ce qu'il faut être supprimé. Cela dit, auto_ptr est i> beaucoup plus délicieux à utiliser ...
@Neil: Qu'est-ce que je disais que quelque chose de similaire avec Auto_PTR pour les tableaux peut être utilisé (et mis en œuvre s'il n'est pas disponible). Le conteneur sait donc transférer la propriété des éléments contenus.
au lieu de
{
std::vector <ArrType> myArr(5);
someExternalRoutine(myArr);
}
Le seul problème que je vois est dans le cas de MYARR devrait être pris en dehors de ce contexte. Vous devez copier le vecteur.
On dirait que vous le dépassez.
plutôt que d'utiliser Essayez {} Catch {} Utilisez le Raii.
Il y a plusieurs façons de le faire sur les commentaires (tous valables). P>
Option 1: option 2: Ceci vous permet également de supprimer le tableau de la ptr_vector lorsque l'objet a une durée de vie plus longue. P>
Si vous avez juste besoin d'un seul (ou d'un ensemble d'artype d'expansion).
Où la durée de vie se termine à la fin de la fonction p>
Si vous avez besoin de plusieurs tableaux d'Arrtype
Où la durée de vie se termine à la fin de la fonction p> Notes sur Essayez {} Catch {} h3>
Ce n'est pas la réinventer la roue; Vous n'avez pas de collection de déchets nativement en C ++.
Je ne peux pas offrir des conseils --Quel est pourquoi je commente, ne répond pas - mais je sais que je fais la même chose dans mes scripts PHP et JS. Et je n'ai jamais vraiment pensé à ce sujet avant. Bonne question, à la hausse votée. =)
Raii est censé traiter cela, mais je ne sais pas comment j'y comprendrais, quelles bibliothèques, etc.
@ tirebowl mais php et js ont la collecte des ordures!
@Phil H Raii (l'acquisition de ressources est l'initialisation) n'est pas une bibliothèque, elle; s une technologie. Si vous ne le comprenez pas, vous lisez les mauvais livres de texte C ++.
@PHIL H: Abandon Votre approche (cette direction réside dans un monde de douleur sans fin) et suivez la réponse de Nick Meyers
ne pas "jeter (s)" Il suffit d'utiliser 'lancer;' Cela relève l'exception originale. Et attraper la référence de const.
@Phil: Au lieu d'attribuer dynamiquement des tableaux, utilisez simplement STD :: Vecteurs, qui incluent déjà Raii.
Et puisque personne n'a répondu à votre question de titre: oui. I>