3 votes

classe basée sur un modèle non virtuel - fuite de mémoire ?

Sur la base de la livre , pp338

#include <iostream>
#include <vector>
#include <string>
#include <ostream>
#include <algorithm>

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/cast.hpp>

using namespace std;

template <typename R, typename Arg> class invoker_base {
public:
  virtual R operator()(Arg arg)=0;
};

template <typename R, typename Arg> class function_ptr_invoker 
  : public invoker_base<R,Arg> {
  R (*func_)(Arg);
public:
  function_ptr_invoker(R (*func)(Arg)):func_(func) {}

  R operator()(Arg arg) {
    return (func_)(arg);
  }
};

template <typename R, typename Arg> class function1 {
  invoker_base<R,Arg>* invoker_;
public:
  function1(R (*func)(Arg)) : 
    invoker_(new function_ptr_invoker<R,Arg>(func)) {}

  R operator()(Arg arg) {
    return (*invoker_)(arg);
  }

  ~function1() {
    delete invoker_;
  }
};

bool some_function(const std::string& s) {
  std::cout << s << " This is really neat\n";
  return true;
}

int main() {
  function1<bool,const std::string&> f1(&some_function);
  f1(std::string("Hello"));
}

Question > le destructeur par défaut de invoker_base n'est PAS virtuel. Existe-t-il une fuite de mémoire dans l'implémentation de function1 ? Comme l'indique le code, le function1::~function1 supprime la ressource allouée par le biais d'un pointeur de classe de base non virtuelle.

6voto

Oli Charlesworth Points 148744

Il n'y a pas de fuite de mémoire ici (l'objet ne possède aucune ressource qui a besoin de delete (-ing).

Cependant, l'invocation de delete sur un objet non-base par le biais d'un pointeur vers la base sans destructeur virtuel provoque un comportement indéfini.

4voto

Dietmar Kühl Points 70604

Ne vous inquiétez pas : il n'y a pas de fuite de mémoire ! Ce qui devrait vous inquiéter, en revanche, c'est que vous avez invoqué un comportement non défini. Ah, bien, cela peut se manifester par une fuite de mémoire mais cela peut aussi se manifester de n'importe quelle autre manière. La règle est très simple : si vous appelez delete sur un pointeur dont le type statique ne correspond pas au type dynamique, vous avez un comportement indéfini. Notez qu'un comportement non défini signifie généralement qu'il fonctionne parfaitement, mais qu'il échoue lorsqu'il y a de grosses sommes d'argent en jeu, par exemple lorsque le client est prêt à accepter le contrat de plusieurs millions si cette seule démo fonctionne - ce qui ne sera pas le cas.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X