root/library/doc/html/memory_management.html @ 651

Revision 651, 8.9 kB (checked in by mido, 15 years ago)

\doc directory cleaned a bit

Line 
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
3<title>mixpp: Memory Management in BDM</title>
4<link href="tabs.css" rel="stylesheet" type="text/css">
5<link href="doxygen.css" rel="stylesheet" type="text/css">
6</head><body>
7<!-- Generated by Doxygen 1.5.9 -->
8<script type="text/javascript">
9<!--
10function changeDisplayState (e){
11  var num=this.id.replace(/[^[0-9]/g,'');
12  var button=this.firstChild;
13  var sectionDiv=document.getElementById('dynsection'+num);
14  if (sectionDiv.style.display=='none'||sectionDiv.style.display==''){
15    sectionDiv.style.display='block';
16    button.src='open.gif';
17  }else{
18    sectionDiv.style.display='none';
19    button.src='closed.gif';
20  }
21}
22function initDynSections(){
23  var divs=document.getElementsByTagName('div');
24  var sectionCounter=1;
25  for(var i=0;i<divs.length-1;i++){
26    if(divs[i].className=='dynheader'&&divs[i+1].className=='dynsection'){
27      var header=divs[i];
28      var section=divs[i+1];
29      var button=header.firstChild;
30      if (button!='IMG'){
31        divs[i].insertBefore(document.createTextNode(' '),divs[i].firstChild);
32        button=document.createElement('img');
33        divs[i].insertBefore(button,divs[i].firstChild);
34      }
35      header.style.cursor='pointer';
36      header.onclick=changeDisplayState;
37      header.id='dynheader'+sectionCounter;
38      button.src='closed.gif';
39      section.id='dynsection'+sectionCounter;
40      section.style.display='none';
41      section.style.marginLeft='14px';
42      sectionCounter++;
43    }
44  }
45}
46window.onload = initDynSections;
47-->
48</script>
49<div class="navigation" id="top">
50  <div class="tabs">
51    <ul>
52      <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
53      <li class="current"><a href="pages.html"><span>Related&nbsp;Pages</span></a></li>
54      <li><a href="annotated.html"><span>Classes</span></a></li>
55      <li><a href="files.html"><span>Files</span></a></li>
56    </ul>
57  </div>
58  <div class="navpath"><a class="el" href="dev_guide2.html">BDM Development - Contribution guide</a>
59  </div>
60</div>
61<div class="contents">
62<h1><a class="anchor" name="memory_management">Memory Management in BDM </a></h1>C++ memory management is notoriously flexible, allowing a wide range of efficient and dangerous techniques. BDM uses conventions which allow high implementation efficiency (not absolutely maximal, but within a measurement error of the most efficient way) while substantially reducing the danger of memory errors. These conventions are described below.<h2><a class="anchor" name="Constructors">
63Constructors</a></h2>
64<ul>
65<li>Each configurable class must have public default constructor (that is, a constructor which takes no parameters). This is required by the configuration framework. Other constructors may also be defined when convenient.</li>
66</ul>
67<ul>
68<li>Each constructor must initialize all fields of the constructed object, to prevent unpredictable behavior.</li>
69</ul>
70One consequence of the points above is the case when a default constructor doesn't have the data with which to initialize a new object - in that case it can simply call the default constructors of all its object fields (and base classes), but must explicitly initialize all numeric fields and raw pointers to 0. Such an object isn't valid as constructed and must have some additional initialization methods (typically from_settings, for reading its configured state), but it can at least be destroyed.<h2><a class="anchor" name="Exceptions">
71Exceptions</a></h2>
72BDM uses exceptions to signal runtime and some logic errors. The library aims to provide the minimal exception safety (that is, throwing an exception doesn't crash and doesn't leak any resources) for all thrown exceptions <b>except</b> memory errors - when a program using BDM exhausts memory, it should be terminated as soon as possible (and in most cases it has probably already terminated by itself). Specific exceptions may provide stronger guarantees, as documented for specific cases. All exceptions thrown out of the library are descendants of std::exception. Since they're organized into a class hierarchy, they should be caught by reference:<p>
73<div class="fragment"><pre class="fragment"><span class="keywordflow">try</span> {
74        mpdf* mtmp = UI::build&lt;mpdf&gt; (_Sources, i);
75        Sources (i) = mtmp;
76} <span class="keywordflow">catch</span> (UIException &amp;exc) {
77</pre></div><p>
78This saves one call to copy constructor and prevents slicing.<h2><a class="anchor" name="Pointers">
79Pointers</a></h2>
80Pointers are used extensively (for efficiency), but usage of raw pointers should be minimized.<p>
81Objects allocated by operator new should be assigned to a smart pointer instance immediately upon their construction, so that they can be automatically deleted after use. BDM implements its own reference-counted smart pointer template, <a class="el" href="classbdm_1_1shared__ptr.html" title="A naive implementation of roughly a subset of the std::tr1::shared_ptr spec.">bdm::shared_ptr</a>, whose interface and semantics are close to the proposed standard std::tr1:shared_ptr (which is planned to replace <a class="el" href="classbdm_1_1shared__ptr.html" title="A naive implementation of roughly a subset of the std::tr1::shared_ptr spec.">bdm::shared_ptr</a> once it becomes widely available). Note that objects allocated on the stack <b>must</b> <b>not</b> have their addresses passed to shared_ptr - that is a bug leading to intermittent runtime errors.<p>
82Non-null heap pointers may also be kept in instances of object_ptr, which is convertible to (and from) shared_ptr. The SHAREDPTR macro (or SHAREDPTR2, for templated types) defines standartized names for these instances, simplifying library usage:<p>
83<div class="fragment"><pre class="fragment"><span class="comment">/*</span>
84<span class="comment"> egamma_ptr is typedef for object_ptr&lt;egamma&gt;, whose default</span>
85<span class="comment"> constructor calls new egamma()</span>
86<span class="comment">*/</span>
87egamma_ptr eG;
88eG-&gt;set_parameters ( a, b );
89
90epdf_array Coms ( 2 ); <span class="comment">// epdf_array is typedef for Array&lt;shared_ptr&lt;epdf&gt; &gt;</span>
91Coms ( 0 ) = eG; <span class="comment">// object_ptr&lt;T&gt; is derived from shared_ptr&lt;T&gt;</span>
92
93<span class="comment">/*</span>
94<span class="comment"> The egamma instance doesn't leak: if the shared_ptr instance which</span>
95<span class="comment"> wraps it isn't assigned to anything else, the pointer is deleted by</span>
96<span class="comment"> the destructor of either object_ptr, or Array, whichever runs last.</span>
97<span class="comment">*/</span>
98</pre></div><p>
99Pointers kept in object fields should be wrapped in a shared_ptr instance, which will automatically keep them valid (at least) for the lifetime of the containing object. When that isn't possible, it should be documented why their containing class doesn't delete them and who does.<p>
100Pointers passed as arguments into functions (and methods) are generally not expected to stay valid after the function returns - when that is required, the parameter's documentation should specify the required scope:<p>
101<div class="fragment"><pre class="fragment"><span class="comment">/* the pointer must stay valid for the lifetime of the object */</span>
102CurrentContext ( <span class="keyword">const</span> <span class="keywordtype">char</span> *name, <span class="keywordtype">int</span> idx );
103</pre></div><p>
104A simpler alternative is just to pass a shared pointer:<p>
105<div class="fragment"><pre class="fragment"><span class="keyword">class </span>mepdf : <span class="keyword">public</span> mpdf
106{
107        shared_ptr&lt;epdf&gt; iepdf;
108<span class="keyword">public</span>:
109        mepdf (shared_ptr&lt;epdf&gt; em) {
110                iepdf = em;
111</pre></div><p>
112In the case above, passing a (constant) reference to <a class="el" href="classbdm_1_1shared__ptr.html">shared_ptr&lt;epdf&gt;</a> might be more efficient, but no measurements have been performed.<p>
113Functions returning raw pointers should document the scope of their validity:<p>
114<div class="fragment"><pre class="fragment"><span class="comment">/*</span>
115<span class="comment"> Returns the stored pointer (which remains owned by this</span>
116<span class="comment"> instance).</span>
117<span class="comment">*/</span>
118T *<span class="keyword">get</span>();
119</pre></div><p>
120Functions generally shouldn't return raw pointers allocated by operator new - such pointers should be wrapped in an instance of shared_ptr, so that the pointer's unlimited life expectancy is encoded in the function signature:<p>
121<div class="fragment"><pre class="fragment"><span class="keyword">virtual</span> shared_ptr&lt;epdf&gt; marginal (<span class="keyword">const</span> RV &amp;rv) <span class="keyword">const</span>;
122</pre></div> </div>
123<hr size="1"><address style="text-align: right;"><small>Generated on Wed Oct 7 17:34:45 2009 for mixpp by&nbsp;
124<a href="http://www.doxygen.org/index.html">
125<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.9 </small></address>
126</body>
127</html>
Note: See TracBrowser for help on using the browser.