//----------------------------------------------------------------------
class DS_CrossBar_Pin
{
public:
CrossBar_AV AV;
AnsiString type_connecteur;
long num_pin;
CrossBar_IO IO;
__fastcall DS_CrossBar_Pin();
};
//-----------------------------------------------------------------------
class DS_CrossBar_Input_Pin : public DS_CrossBar_Pin
{
public:
DS_CrossBar_Input_Pin *related_in;
__fastcall DS_CrossBar_Input_Pin();
};
//-----------------------------------------------------------------------
class DS_CrossBar_Output_Pin : public DS_CrossBar_Pin
{
private:
std::vector<DS_CrossBar_Input_Pin *> routing_list;
//----------------------------------------------------------------------
Dans DS_CrossBar_Infos::Get_Pins() je remplis les vecteurs output_pins et
input_pins à coups de push_back:
Mais dans ce cas est-ce que toutes les libérations de mémoire se feront correctement?
Je n'ai pas lu toute la discussion, mais tu ne fournis pas les elements necessaires pour repondre.
Les pointeurs intelligents ne sont qu'un moyen d'implementer une polique de gestion de la memoire. Il faut decider de la polique d'abord, puis choisir le type de pointeur adequat.
La chose a regarder est quels sont les pointeurs qui peuvent maintenir l'objet en vie.
Un des problemes supplementaire avec l'utilisation du comptage de reference est la gestion des cycles. S'il y en a, il faut les casser a la main car sinon la memoire ne sera jamais liberee.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Michael <michael@no.com> writes:
Mais dans ce cas est-ce que toutes les libérations de mémoire se
feront correctement?
Je n'ai pas lu toute la discussion, mais tu ne fournis pas les
elements necessaires pour repondre.
Les pointeurs intelligents ne sont qu'un moyen d'implementer une
polique de gestion de la memoire. Il faut decider de la polique
d'abord, puis choisir le type de pointeur adequat.
La chose a regarder est quels sont les pointeurs qui peuvent maintenir
l'objet en vie.
Un des problemes supplementaire avec l'utilisation du comptage de
reference est la gestion des cycles. S'il y en a, il faut les casser
a la main car sinon la memoire ne sera jamais liberee.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Mais dans ce cas est-ce que toutes les libérations de mémoire se feront correctement?
Je n'ai pas lu toute la discussion, mais tu ne fournis pas les elements necessaires pour repondre.
Les pointeurs intelligents ne sont qu'un moyen d'implementer une polique de gestion de la memoire. Il faut decider de la polique d'abord, puis choisir le type de pointeur adequat.
La chose a regarder est quels sont les pointeurs qui peuvent maintenir l'objet en vie.
Un des problemes supplementaire avec l'utilisation du comptage de reference est la gestion des cycles. S'il y en a, il faut les casser a la main car sinon la memoire ne sera jamais liberee.
A+
-- Jean-Marc FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html Site de usenet-fr: http://www.usenet-fr.news.eu.org
Patrick Mézard
Michael wrote:
Pour m'expliquer autrement, j'ai toujours les classes:
Maintenant je dois faire pointer A::*related_in vers une instance de A de vect_A. Seulement maintenant vect_A contient un shared_ptr<A>.
Question:
je laisse tel quel et je fais par exemple:
a.related_in = vect_B.begin().get();
a.related_in = vect_B.begin()->get();
ou bien alors:
struct A { boost::shared_ptr<A> related_in; };
et ensuite a.related_in = vect_B.begin();
a.related_in = *vect_B.begin();
Mais dans ce cas suis-je sûr que related_in pointe bien vers l'instance de A voulue, et suis-je sûr que la libération de la mémoire est complète?
Ca dépend... Les boost::shared_ptr sont des pointeurs intelligents à comptage de références. Ca signifie que l'objet pointé n'est détruit que lorsque la dernière instance de shared_ptr le référençant disparait.
Maintenant, pour reprendre les termes de Jean-Marc, il faut définir une politique de gestion de mémoire. S'il est garanti que "vect_A", "vect_B" et les pointeurs qu'ils contiennent ne sont plus modifiés une fois remplis, et que cela tient durant toutes le manipulation d'instances de A et B, alors tu peux te contenter de récupérer les pointeurs via get(). Il n'arrivera en effet jamais qu'un élément pointé par "related_in" ou un autre pointeur "nu" soit détruit à son insu.
Si "vect_A", "vect_B" ou leur contenu peuvent changer, en effaçant un élément par exemple, alors tout se complique. Ca ne signifie pas pour autant que tu doives remplacer tes pointeurs "nus" par des shared_ptr, plutôt que tu doives conserver le fameux invariant <"related_in" est NULL ou pointe sur une instance existante>, le shared_ptr n'étant qu'un moyen pas forcément très *logique" de conserver cet invariant (de fait ils empêchent la destruction de l'objet tant qu'ils le référencent). Ce qui est logique, c'est que lorsque tu enlèves un élément de "vect_A", ça signifie quelque part que tu le retires de ton graphe, donc *au préalable tu dois défaire tous les liens le référençant au sein de ton graphe*. Si tu fais ça, en mettant tous le pointeurs le référençant à NULL par exemple, alors tes invariants seront valides une fois l'objet détruit. Ce qui arrivera une fois que l'instance du shared_ptr de "vect_A" aura disparue.
Note que si tu prends soin d'enlever toutes le références à l'objet dans ton graphe avant de le retirer de "vect_A", alors les cycles qui pourraient exister sont naturellement brisés. Mettre des shared_ptr à la place de pointeurs nus fonctionneraient sans problèmes mais ce serait complètement inutile.
Patrick Mézard
Michael wrote:
Pour m'expliquer autrement, j'ai toujours les classes:
Maintenant je dois faire pointer A::*related_in vers une instance de A de
vect_A. Seulement maintenant vect_A contient un shared_ptr<A>.
Question:
je laisse tel quel et je fais par exemple:
a.related_in = vect_B.begin().get();
a.related_in = vect_B.begin()->get();
ou bien alors:
struct A
{
boost::shared_ptr<A> related_in;
};
et ensuite
a.related_in = vect_B.begin();
a.related_in = *vect_B.begin();
Mais dans ce cas suis-je sûr que related_in pointe bien vers l'instance de
A voulue, et suis-je sûr que la libération de la mémoire est complète?
Ca dépend...
Les boost::shared_ptr sont des pointeurs intelligents à comptage de
références. Ca signifie que l'objet pointé n'est détruit que lorsque la
dernière instance de shared_ptr le référençant disparait.
Maintenant, pour reprendre les termes de Jean-Marc, il faut définir une
politique de gestion de mémoire. S'il est garanti que "vect_A", "vect_B"
et les pointeurs qu'ils contiennent ne sont plus modifiés une fois
remplis, et que cela tient durant toutes le manipulation d'instances de
A et B, alors tu peux te contenter de récupérer les pointeurs via get().
Il n'arrivera en effet jamais qu'un élément pointé par "related_in" ou
un autre pointeur "nu" soit détruit à son insu.
Si "vect_A", "vect_B" ou leur contenu peuvent changer, en effaçant un
élément par exemple, alors tout se complique. Ca ne signifie pas pour
autant que tu doives remplacer tes pointeurs "nus" par des shared_ptr,
plutôt que tu doives conserver le fameux invariant <"related_in" est
NULL ou pointe sur une instance existante>, le shared_ptr n'étant qu'un
moyen pas forcément très *logique" de conserver cet invariant (de fait
ils empêchent la destruction de l'objet tant qu'ils le référencent). Ce
qui est logique, c'est que lorsque tu enlèves un élément de "vect_A", ça
signifie quelque part que tu le retires de ton graphe, donc *au
préalable tu dois défaire tous les liens le référençant au sein de ton
graphe*. Si tu fais ça, en mettant tous le pointeurs le référençant à
NULL par exemple, alors tes invariants seront valides une fois l'objet
détruit. Ce qui arrivera une fois que l'instance du shared_ptr de
"vect_A" aura disparue.
Note que si tu prends soin d'enlever toutes le références à l'objet dans
ton graphe avant de le retirer de "vect_A", alors les cycles qui
pourraient exister sont naturellement brisés. Mettre des shared_ptr à la
place de pointeurs nus fonctionneraient sans problèmes mais ce serait
complètement inutile.
Maintenant je dois faire pointer A::*related_in vers une instance de A de vect_A. Seulement maintenant vect_A contient un shared_ptr<A>.
Question:
je laisse tel quel et je fais par exemple:
a.related_in = vect_B.begin().get();
a.related_in = vect_B.begin()->get();
ou bien alors:
struct A { boost::shared_ptr<A> related_in; };
et ensuite a.related_in = vect_B.begin();
a.related_in = *vect_B.begin();
Mais dans ce cas suis-je sûr que related_in pointe bien vers l'instance de A voulue, et suis-je sûr que la libération de la mémoire est complète?
Ca dépend... Les boost::shared_ptr sont des pointeurs intelligents à comptage de références. Ca signifie que l'objet pointé n'est détruit que lorsque la dernière instance de shared_ptr le référençant disparait.
Maintenant, pour reprendre les termes de Jean-Marc, il faut définir une politique de gestion de mémoire. S'il est garanti que "vect_A", "vect_B" et les pointeurs qu'ils contiennent ne sont plus modifiés une fois remplis, et que cela tient durant toutes le manipulation d'instances de A et B, alors tu peux te contenter de récupérer les pointeurs via get(). Il n'arrivera en effet jamais qu'un élément pointé par "related_in" ou un autre pointeur "nu" soit détruit à son insu.
Si "vect_A", "vect_B" ou leur contenu peuvent changer, en effaçant un élément par exemple, alors tout se complique. Ca ne signifie pas pour autant que tu doives remplacer tes pointeurs "nus" par des shared_ptr, plutôt que tu doives conserver le fameux invariant <"related_in" est NULL ou pointe sur une instance existante>, le shared_ptr n'étant qu'un moyen pas forcément très *logique" de conserver cet invariant (de fait ils empêchent la destruction de l'objet tant qu'ils le référencent). Ce qui est logique, c'est que lorsque tu enlèves un élément de "vect_A", ça signifie quelque part que tu le retires de ton graphe, donc *au préalable tu dois défaire tous les liens le référençant au sein de ton graphe*. Si tu fais ça, en mettant tous le pointeurs le référençant à NULL par exemple, alors tes invariants seront valides une fois l'objet détruit. Ce qui arrivera une fois que l'instance du shared_ptr de "vect_A" aura disparue.
Note que si tu prends soin d'enlever toutes le références à l'objet dans ton graphe avant de le retirer de "vect_A", alors les cycles qui pourraient exister sont naturellement brisés. Mettre des shared_ptr à la place de pointeurs nus fonctionneraient sans problèmes mais ce serait complètement inutile.