Skip to content

Comment empécher l'allocation dynamique d'un objet en C++

Technique trouvée sur un blog consacré à l'informatique : on ne fait pas de la magie.

Pour interdire l'allocation dynamique d'un objet, il suffit de définir un opérateur new() comme ci-dessous pour la classe de l'objet.
class maClasse {
public:
        void *operator new (size_t taille) {
                throw 0;
                return new int; // peut renvoyer n'importe quoi : on ne passera jamais ici
        }
};

Mais quel est l'intérêt d'interdire ainsi l'allocation dynamique ?
Un objet d'une telle classe ne pourrait qu'être alloué dans la pile :
maClasse objet; // OK

maClasse *pointeur = new maClasse(); // produit une exception.

C'est un moyen de forcer l'utilisation de la technique d'acquisition de ressources par initialisation.

Prenons l'exemple d'un protection d'un code contre l'utilisation simultanée par plusieurs processus. Sous Unix, on peut utiliser des sémaphores, ressources système, pour faire une telle mutuelle exclusion. Supposons que l'utilisation des sémaphores, dans ce cas, soit encapsulée, dans le respect de l'acquisition de ressources par initialisation, dans la classe MUTEX.

Pour protéger une section de code code on écrirait :
 {
    MUTEX mux("mymux.mux"); // acquisition d'une sémaphore UNIX

    ... code critique (protégé contre un accès simultané)...

 } // libération automatique

Évidemment dans ce cas là, on veut éviter l'allocation d'un objet de type MUTEX par l'opérateur new() qui échappant à la libération automatique pourrait bloquer le système.

Bref, en empêchant l'allocation dynamique, on force la bonne utilisation du C++, ce qui peut être utile vis à vis de programmeurs qui auraient pris de mauvaises habitudes en JAVA. :-)

Rétroliens

Pas de rétroliens

Commentaires

Afficher les commentaires en Vue non groupée | Vue groupée

ZeGuigui sur :

Sauf qu'en Java on n'est pas obligé de passer par des artifices compliqués pour protéger un bout de code contre l'utilisation simultanée par plusieurs processus... c'est prévu dès la déclaration (il suffit de déclarer le code comme "synchronized").

Mais bon je suis certain qu'on peut trouver d'autres usages intéressants à cette méthode... le tout étant qu'on sache que c'est possible !

Sébastien sur :

Il ne s'agissait bien sûr que d'un exemple (lire l'article sur l'acquisition de ressource par initialisation pour voir l'intérêt de la technique). La technique du garbage collector de JAVA est très limitée et ne permet pas en général de traiter les ressources autres que la mémoire. D'ailleurs en C++ ou de très bon garbage collector existent, on ne voit pratiquement jamais cette technique mise en oeuvre dans la pratique à cause de ses limitations d'une part et aussi du fait que ces librairies ne sont pas considérées comme faisant partie du langage.

Par ailleurs, pour la protection de code, la méthode native implémentée par Java ne marche qu'en JAVA et ne permet par de communiquer avec des processus non-JAVA ou des processus JAVA hébergés par un autre machine virtuelle. Elle fait appel à un multitâche basé sur des threads et non pas sur le système.

Il existe en JAVA une implémentation des sémaphores système. Quand j'avais cherché , il y a quelques années, une telle fonctionalité, j'étais même tombé sur 5 ou 6 implémentations dont l'avenir n'était pas très clair (cas classique lorsqu'on sort des fonctionalités implémentées par Sun). Elles souffraient évidemment toutes du problème évoqué dans l'article : si on oublie de libérer on bloque tout. Il faut systématiquement faire des try finally en JAVA car il n'existe pas de mécanisme de nettoyage automatique basé sur les destructeurs comme en C++.

Ajouter un commentaire

Marquer un texte en gras: *mot*, souligner un texte: _mot_.
Les smilies standard comme :-) et ;-) sont convertis en images.
:'(  :-)  :-|  :-O  :-(  8-)  :-D  :-P  ;-) 
Les adresses Email ne sont pas affichées, et sont seulement utilisées pour la communication.
Form options