Derniers messages sur Zeste de Savoirhttps://zestedesavoir.com/forums/2018-02-06T20:41:15+01:00Les derniers messages parus sur le forum de Zeste de Savoir.Boost::serialization pointeur avec gestion de mémoire externe via unique_ptr, message #1734882018-02-06T20:41:15+01:00germinolegrand/@germinolegrandhttps://zestedesavoir.com/forums/sujet/10189/boostserialization-pointeur-avec-gestion-de-memoire-externe-via-unique_ptr/?page=1#p173488<p>Je vois pas bien comment faire autrement…</p>Boost::serialization pointeur avec gestion de mémoire externe via unique_ptr, message #1730392018-01-31T20:58:49+01:00Davidbrcz/@Davidbrczhttps://zestedesavoir.com/forums/sujet/10189/boostserialization-pointeur-avec-gestion-de-memoire-externe-via-unique_ptr/?page=1#p173039<p>Personne n’a de remarque ?</p>Boost::serialization pointeur avec gestion de mémoire externe via unique_ptr, message #1726332018-01-26T18:47:36+01:00Davidbrcz/@Davidbrczhttps://zestedesavoir.com/forums/sujet/10189/boostserialization-pointeur-avec-gestion-de-memoire-externe-via-unique_ptr/?page=1#p172633<p>Bonjour à tous.</p>
<p>Je souhaite sérialiser une structure d’arbre la relation entre les différents noeuds est assurée par des pointeurs nus (ie T*) et la mémoire est gérée par un<code>vector<unique_ptr<T>></code> à coté. </p>
<p>Pour assurer la sérialisation, je teste boost::serialization et les premières expérimentations m’impressionnent. La bibliothqèe arrive à reconstruire une structure d’arbre en mémoire avec assez peu d’effort.</p>
<p>Le problème, c’est que les pointeurs nus deviennent responsable de la mémoire ! Et ca c’est pas cool du tout.
Il faut donc re-transférer la gestion de la mémoire au vecteur qui va bien.</p>
<p>J’ai une solution illustrée dans le code ci dessous. En guise de test, je créer 10 objets de A et je vais stocker un tableau qui contient 2 fois chaque objet sous forme de pointeur. Ca sert à simuler les noeuds partagés que j’ai dans mon arbre. Lors de la relecture, je vais créer après avoir tout lu, un unique_pointeur pour chaque pointeur lu, en prenant garde d’éviter d’en créer si l’adresse est déjà présente dans la liste (pour éviter un double delete).</p>
<p>Le seul problème que je vois, c’est qu’entre la lecture du tableau et la création des <code>unique_ptr</code>, la mémoire n’est géré par personne. Mais je survirai </p>
<div><table class="codehilitetable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99</pre></div></td><td class="code"><div class="codehilite"><pre><span></span><span class="cp">#include</span> <span class="cpf"><boost/archive/text_iarchive.hpp></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><boost/archive/text_oarchive.hpp></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><boost/serialization/export.hpp></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><boost/serialization/serialization.hpp></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><boost/serialization/split_member.hpp></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><boost/serialization/vector.hpp></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><iostream></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><vector></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><fstream></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><memory></span><span class="cp"></span>
<span class="k">struct</span> <span class="n">A</span><span class="p">{</span>
<span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
<span class="n">A</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">)</span><span class="o">:</span><span class="n">i</span><span class="p">(</span><span class="n">n</span><span class="p">){}</span>
<span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Archive</span><span class="o">></span>
<span class="kt">void</span> <span class="n">serialize</span><span class="p">(</span><span class="n">Archive</span> <span class="o">&</span><span class="n">ar</span><span class="p">,</span> <span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">version</span><span class="p">)</span> <span class="p">{</span>
<span class="n">ar</span> <span class="o">&</span><span class="n">i</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">private</span><span class="o">:</span>
<span class="k">friend</span> <span class="k">class</span> <span class="nc">boost</span><span class="o">::</span><span class="n">serialization</span><span class="o">::</span><span class="n">access</span><span class="p">;</span>
<span class="n">A</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">struct</span> <span class="n">Test</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">A</span><span class="o">>></span> <span class="n">mem_store</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">A</span><span class="o">*></span> <span class="n">to_store</span><span class="p">;</span>
<span class="n">Test</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
<span class="n">Test</span><span class="p">(</span><span class="kt">bool</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
<span class="n">mem_store</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">make_unique</span><span class="o"><</span><span class="n">A</span><span class="o">></span><span class="p">(</span><span class="n">i</span><span class="p">));</span>
<span class="p">}</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">n</span> <span class="o"><</span> <span class="mi">2</span><span class="p">;</span> <span class="o">++</span><span class="n">n</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="k">const</span> <span class="o">&</span><span class="nl">ptr</span> <span class="p">:</span> <span class="n">mem_store</span><span class="p">)</span> <span class="p">{</span>
<span class="n">to_store</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">ptr</span><span class="p">.</span><span class="n">get</span><span class="p">());</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">private</span><span class="o">:</span>
<span class="k">friend</span> <span class="k">class</span> <span class="nc">boost</span><span class="o">::</span><span class="n">serialization</span><span class="o">::</span><span class="n">access</span><span class="p">;</span>
<span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Archive</span><span class="o">></span>
<span class="kt">void</span> <span class="n">save</span><span class="p">(</span><span class="n">Archive</span> <span class="o">&</span><span class="n">ar</span><span class="p">,</span> <span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">version</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span>
<span class="n">ar</span> <span class="o">&</span><span class="n">to_store</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">template</span> <span class="o"><</span><span class="k">class</span> <span class="nc">Archive</span><span class="o">></span> <span class="kt">void</span> <span class="n">load</span><span class="p">(</span><span class="n">Archive</span> <span class="o">&</span><span class="n">ar</span><span class="p">,</span> <span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">version</span><span class="p">)</span> <span class="p">{</span>
<span class="n">ar</span> <span class="o">&</span><span class="n">to_store</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="nl">ptr_raw</span> <span class="p">:</span> <span class="n">to_store</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">find_if</span><span class="p">(</span><span class="n">mem_store</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">mem_store</span><span class="p">.</span><span class="n">end</span><span class="p">(),</span>
<span class="p">[</span><span class="n">ptr_raw</span><span class="p">](</span><span class="k">auto</span> <span class="k">const</span> <span class="o">&</span><span class="n">stored_ptr</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">ptr_raw</span> <span class="o">==</span> <span class="n">stored_ptr</span><span class="p">.</span><span class="n">get</span><span class="p">();</span>
<span class="p">})</span> <span class="o">==</span> <span class="n">mem_store</span><span class="p">.</span><span class="n">end</span><span class="p">())</span> <span class="p">{</span>
<span class="n">mem_store</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">unique_ptr</span><span class="o"><</span><span class="n">A</span><span class="o">></span><span class="p">(</span><span class="n">ptr_raw</span><span class="p">));</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="n">BOOST_SERIALIZATION_SPLIT_MEMBER</span><span class="p">()</span>
<span class="p">};</span>
<span class="n">BOOST_CLASS_EXPORT_GUID</span><span class="p">(</span><span class="n">Test</span><span class="p">,</span> <span class="s">"Test"</span><span class="p">);</span>
<span class="n">BOOST_CLASS_EXPORT_GUID</span><span class="p">(</span><span class="n">A</span><span class="p">,</span> <span class="s">"A"</span><span class="p">);</span>
<span class="kt">void</span> <span class="nf">store</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// create and open a character archive for output</span>
<span class="n">std</span><span class="o">::</span><span class="n">ofstream</span> <span class="n">ofs</span><span class="p">(</span><span class="s">"arxiv"</span><span class="p">);</span>
<span class="n">boost</span><span class="o">::</span><span class="n">archive</span><span class="o">::</span><span class="n">text_oarchive</span> <span class="n">oa</span><span class="p">(</span><span class="n">ofs</span><span class="p">);</span>
<span class="n">Test</span> <span class="n">t</span><span class="p">{</span><span class="nb">true</span><span class="p">};</span>
<span class="n">oa</span> <span class="o"><<</span> <span class="n">t</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">reload</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// create and open an archive for input</span>
<span class="n">std</span><span class="o">::</span><span class="n">ifstream</span> <span class="n">ifs</span><span class="p">(</span><span class="s">"arxiv"</span><span class="p">);</span>
<span class="n">boost</span><span class="o">::</span><span class="n">archive</span><span class="o">::</span><span class="n">text_iarchive</span> <span class="n">ia</span><span class="p">(</span><span class="n">ifs</span><span class="p">);</span>
<span class="n">Test</span> <span class="n">t</span><span class="p">;</span>
<span class="n">ia</span> <span class="o">>></span> <span class="n">t</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="nl">ptr_raw</span> <span class="p">:</span> <span class="n">t</span><span class="p">.</span><span class="n">to_store</span><span class="p">)</span> <span class="p">{</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="n">ptr_raw</span> <span class="o"><<</span><span class="s">" "</span><span class="o"><<</span><span class="n">ptr_raw</span><span class="o">-></span><span class="n">i</span><span class="o"><<</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"FINAl SIZE "</span> <span class="o"><<</span> <span class="n">t</span><span class="p">.</span><span class="n">mem_store</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o"><<</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="n">store</span><span class="p">();</span>
<span class="n">reload</span><span class="p">();</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p>Valgrind est content, ca marche, mais est ce que c’est juste ? Y’a-t-il autre chose (un bug/une faille) que j’aurai loupé ?</p>
<p>Merci !
David </p>