OVH Cloud OVH Cloud

auto_ptr et vérification que le pointeur est bien alloué ?

12 réponses
Avatar
Stephane Wirtel
bonjour,

Est-il possible de vérifier qu'un pointeur intélligent est bien alloué ou pas ?
style :

auto_ptr <TypeVariable> ptr (new TypeVariable ("Toto"));
if (ptr) {
}

Je pose la question, car je l'avais mis dans un 'try' 'catch' en espérant que si l'allocation
se déroulerait mal, celui-ci lancerait une exception, mais rien de tel ne se produit.

Merci,

Stéphane

2 réponses

1 2
Avatar
Stephane Wirtel
Ça veut dire quoi, une meilleure conception ? Il y a d'autres
pointeurs intelligents en Boost, avec d'autres sémantiques. Dans
la pratique, on a :

boost::scoped_ptr :
Le plus simple, il ne supporte pas la copie ni
l'affectation. Pour des membres des classes qui ne les
supportent pas non plus, c'est exactement ce qu'il faut. Ne
peut pas servir dans des collections STL.

std::auto_ptr :
À utiliser chaque fois qu'un transfert de responsibilités
est désiré. Valeur de retour d'une fonction, évidemment,
mais il me sert aussi quand je passe des objets entre des
threads. Ne peut pas servir dans des collections STL.

boost::shared_ptr/boost::weak_ptr :
Beaucoup plus complexe et lourd, mais avec une sémantique de
responsibilité partagée. Avec un peu d'attention, peut
remplacer un glaneur de cellules dans beaucoup de cas. C'est
donc le plus complet -- mais le plus complexe à utiliser
aussi, du fait qu'il y a deux types de pointeurs. (Il y a
aussi des problèmes quand on doit convertir le pointeur brut
en un pointeur intelligent à plusieurs endroits différents.)

pointeur à comptage de références invasifs :
Pas de standard, mais dans la mésure que les exemples ont
aparus dans plusieurs livres (dont Scott Meyers), il est
assez repandu. En gros, l'utilisation récouvre celle de
boost::shared_ptr, sans les weak_ptr, avec un mechanisme
bien moins lourd et plus robuste, mais avec le désavantage
non-negligeable qu'il faut que l'objet auquel il pointe
dérive d'une classe prédéfinie (RefCntObj, RfObject, ou
quelque chose du genre).

Il y a aussi sans doute bien d'autres variantes.

Les pointeurs boost ont aussi la particularité qu'on peut leur
spécifier que faire lors de la « destruction ». On pourrait donc
imaginer un boost::shared_ptr qui, à la place de détruire
l'objet, libérer seulement un lock.


Merci pour l'explication. Effectivement, j'ai commencé à utilisé les auto_ptr parce que je voulais responsabiliser une classe
à ma place, ce qui me permettrait de penser beaucoup plus aux fonctionnalités du code, qu'au debuggage des pointeurs non-désalloués.

Par contre, je vois "pointeur à comptage de références invasifs", me donne l'idée de surcharger new, new[], delete, delete[], et de mettre
mon propre gestionnaire de mémoire, afin de pouvoir faire des statistiques sur les ressources allouées, et voir si je n'oublie pas quelque part
une désallocation.

A long terme, faire la même chose, pour les accès bases de données, accès fichiers, accès réseaux (connection par état).

Suis-je un doux rêveur, ou est-ce possible ?

Stéphane

Avatar
kanze
Stephane Wirtel wrote:

Par contre, je vois "pointeur à comptage de références
invasifs", me donne l'idée de surcharger new, new[], delete,
delete[], et de mettre mon propre gestionnaire de mémoire,
afin de pouvoir faire des statistiques sur les ressources
allouées, et voir si je n'oublie pas quelque part une
désallocation.


Le surcharge des opérateurs new et delete est assez courant chez
ceux qui ne peuvent pas se payer Purify. J'ai moi-même une
version qui maintient une liste des blocs libres (parmi les
blocs alloués pendant que l'instance de la vérification était
active, ce qui permet à tester les sous-ensembles pour des
fuites) ; en plus, il met des zones de garde avant et après le
bloc (pour detecter les écritures au delà des bornes), avec
différentes « signatures » qui permet la detection des deletes
doubles ou des deletes de la mémoire non allouée par new, et il
écrit toute la mémoire avec des valeurs bidons et à l'allocation
(pour une detection de la mémoire non initialisée) et à la
libération (pour une detetction de l'utilisation après la
libération).

Quand je sais le faire, je mets aussi une trace de la pile dans
chaque bloc, que je sors (en hex) en cas d'erreur. Ça permet à
determiner exactement où le bloc en question a été alloué, ce
qui aide pas mal au débogguage.

A long terme, faire la même chose, pour les accès bases de
données, accès fichiers, accès réseaux (connection par état).

Suis-je un doux rêveur, ou est-ce possible ?


Tout à fait. J'ai déjà travaillé sur un projet où des pointeurs
intelligent géraient la verouillage en mémoire des objets
normalement maintenus sur disque. L'initialisation du pointeur
avec un identificateur déclencher la lecture de l'objet du
disque s'il n'était pas encore en mémoire. L'image de l'objet en
mémoire contenait aussi un compteur de références (comptage
invasif), et au besoin, on virait de la mémoire les objets dont
le compteur était zéro. (On réécrivait tous les objets modifiés
à la fin de chaque transaction, de façon synchrone, avant
d'envoyer l'acquittement de la transaction.)

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

1 2