8
votes

Suis-je fou de recréer un petit système de collecte des ordures à l'intérieur de mes fonctions?

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 code>, dont je peux simplement supprimer chaque article Quand j'attrape une exception, comme ceci:

try
{
   set<ArrType*> sHeap;
   ArrType* myArr = new ArrType[5];
   sHeap.Add(myArr);
   someExternalRoutine(myArr);
   ...
} 
catch(CString s)
{
   DeleteAllPointersInMyHeap(sHeap);
   throw(s);
}


9 commentaires

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.


5 Réponses :


10
votes

Vous devez utiliser un Raii Techinque. Vous déléguez la destruction à un autre objet que vous créez sur la pile.

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.


0 commentaires

19
votes

Pourquoi ne pas utiliser un pointeur intelligent comme boost :: Shared_array ou utilisez une pile-alloué std :: vecteur ? Pour les allocations simples plutôt que des allocations de tableau, vous pouvez utiliser Boost :: partagé_ptr .

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.


0 commentaires

2
votes

Vous n'avez pas à compter sur la collecte des ordures.

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.

Vous pouvez mettre en œuvre quelque chose de similaire pour les tableaux.


3 commentaires

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 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.



8
votes

au lieu de

{
   std::vector <ArrType> myArr(5);
   someExternalRoutine(myArr);
}


1 commentaires

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.



2
votes

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).

Option 1:

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 xxx

option 2:

Si vous avez besoin de plusieurs tableaux d'Arrtype Où la durée de vie se termine à la fin de la fonction xxx

Ceci vous permet également de supprimer le tableau de la ptr_vector lorsque l'objet a une durée de vie plus longue.

Notes sur Essayez {} Catch {}
  • Catch de Ref
    • Si vous attrapez un type spécifique, vous êtes sensible au problème de la coupe, car les types dérivés sont en copie construits dans la variable définie dans l'expression de capture.
    • préfère attraper la const ref
    • lors de la reproduction de coup d'utilisation; (Sans l'expression)
      • Cela rejette l'exception originale plutôt que de copier la nouvelle exception à l'endroit où le mécanisme de traitement des exceptions cache l'exception lors de la déruisement de la pile.


0 commentaires