root/library/doc/tutorial/memory_management.dox @ 680

Revision 613, 5.0 kB (checked in by smidl, 15 years ago)

documentation

Line 
1/*!
2\page memory_management Memory Management in BDM
3
4C++ memory management is notoriously flexible, allowing a wide range
5of efficient and dangerous techniques. BDM uses conventions which
6allow high implementation efficiency (not absolutely maximal, but
7within a measurement error of the most efficient way) while
8substantially reducing the danger of memory errors. These conventions
9are described below.
10
11\section Constructors
12
13\li Each configurable class must have public default constructor (that
14is, a constructor which takes no parameters). This is required by the
15configuration framework. Other constructors may also be defined when
16convenient.
17
18\li Each constructor must initialize all fields of the constructed
19object, to prevent unpredictable behavior.
20
21One consequence of the points above is the case when a default
22constructor doesn't have the data with which to initialize a new
23object - in that case it can simply call the default constructors of
24all its object fields (and base classes), but must explicitly
25initialize all numeric fields and raw pointers to 0. Such an object
26isn't valid as constructed and must have some additional
27initialization methods (typically from_settings, for reading its
28configured state), but it can at least be destroyed.
29
30\section Exceptions
31
32BDM uses exceptions to signal runtime and some logic errors. The
33library aims to provide the minimal exception safety (that is,
34throwing an exception doesn't crash and doesn't leak any resources)
35for all thrown exceptions \b except memory errors - when a program
36using BDM exhausts memory, it should be terminated as soon as possible
37(and in most cases it has probably already terminated by
38itself). Specific exceptions may provide stronger guarantees, as
39documented for specific cases. All exceptions thrown out of the
40library are descendants of std::exception. Since they're organized
41into a class hierarchy, they should be caught by reference:
42
43\code
44try {
45        mpdf* mtmp = UI::build<mpdf> (_Sources, i);
46        Sources (i) = mtmp;
47} catch (UIException &exc) {
48\endcode
49
50This saves one call to copy constructor and prevents slicing.
51
52\section Pointers
53
54Pointers are used extensively (for efficiency), but usage of raw
55pointers should be minimized.
56
57Objects allocated by operator new should be assigned to a smart
58pointer instance immediately upon their construction, so that they can
59be automatically deleted after use. BDM implements its own
60reference-counted smart pointer template, bdm::shared_ptr, whose
61interface and semantics are close to the proposed standard
62std::tr1:shared_ptr (which is planned to replace bdm::shared_ptr once
63it becomes widely available). Note that objects allocated on the stack
64\b must \b not have their addresses passed to shared_ptr - that is a
65bug leading to intermittent runtime errors.
66
67Non-null heap pointers may also be kept in instances of object_ptr,
68which is convertible to (and from) shared_ptr. The SHAREDPTR macro (or
69SHAREDPTR2, for templated types) defines standartized names for these
70instances, simplifying library usage:
71
72\code
73/*
74 egamma_ptr is typedef for object_ptr<egamma>, whose default
75 constructor calls new egamma()
76*/
77egamma_ptr eG;
78eG->set_parameters ( a, b );
79
80epdf_array Coms ( 2 ); // epdf_array is typedef for Array<shared_ptr<epdf> >
81Coms ( 0 ) = eG; // object_ptr<T> is derived from shared_ptr<T>
82
83/*
84 The egamma instance doesn't leak: if the shared_ptr instance which
85 wraps it isn't assigned to anything else, the pointer is deleted by
86 the destructor of either object_ptr, or Array, whichever runs last.
87*/
88\endcode
89
90Pointers kept in object fields should be wrapped in a shared_ptr
91instance, which will automatically keep them valid (at least) for the
92lifetime of the containing object. When that isn't possible, it should
93be documented why their containing class doesn't delete them and who
94does.
95
96Pointers passed as arguments into functions (and methods) are
97generally not expected to stay valid after the function returns - when
98that is required, the parameter's documentation should specify the
99required scope:
100
101\code
102/* the pointer must stay valid for the lifetime of the object */
103CurrentContext ( const char *name, int idx );
104\endcode
105
106A simpler alternative is just to pass a shared pointer:
107
108\code
109class mepdf : public mpdf
110{
111        shared_ptr<epdf> iepdf;
112public:
113        mepdf (shared_ptr<epdf> em) {
114                iepdf = em;
115\endcode
116
117In the case above, passing a (constant) reference to shared_ptr<epdf>
118might be more efficient, but no measurements have been performed.
119
120Functions returning raw pointers should document the scope of their
121validity:
122
123\code
124/*
125 Returns the stored pointer (which remains owned by this
126 instance).
127*/
128T *get();
129\endcode
130
131Functions generally shouldn't return raw pointers allocated by
132operator new - such pointers should be wrapped in an instance of
133shared_ptr, so that the pointer's unlimited life expectancy is encoded
134in the function signature:
135
136\code
137virtual shared_ptr<epdf> marginal (const RV &rv) const;
138\endcode
139
140*/
Note: See TracBrowser for help on using the browser.