    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Elephant - A C++ Memory Observer</title>
        <link>https://members.accu.org/index.php/articles/786</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + CVu Journal Vol 17, #1 - Feb 2005</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c98/">171</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-98/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+98/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Elephant - A C++ Memory Observer</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 February 2005 13:16:10 +00:00 or Thu, 03 February 2005 13:16:10 +00:00</p>
<p><strong>Summary:</strong>&nbsp;<p>Elephant is a C++ memory observer. It keeps track of all calls to new and delete via custom implementations of operator new and operator delete. </p></p>
<p><strong>Body:</strong>&nbsp;<div class="article" lang="en">
<div class="titlepage">
<div>
<div>
<h2><a name="d0e1" id="d0e1"></a>Elephant - A C++
Memory Observer</h2>
</div>
<div class="author">
<h3><span class="firstname">Paul</span> <span class=
"surname">Grenyer</span></h3>
<tt class="email">&lt;<a href=
"mailto:paul@paulgrenyer.co.uk">paul@paulgrenyer.co.uk</a>&gt;</tt></div>
</div>
<hr></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a>What is
Elephant?</h2>
</div>
<p>Elephant is a C++ memory observer. It keeps track of all calls
to <tt class="function">new</tt> and <tt class=
"function">delete</tt> via custom implementations of <tt class=
"methodname">operator new</tt> and <tt class="methodname">operator
delete</tt>. Observers can register to be notified of allocations
and deletions and used to detect memory leaks, keep a track of
maximum memory usage or for any other purpose, by implementing a
simple interface.</p>
<p>A notification of an allocation consists of the address and size
of the memory allocated. The line number, function name and file
name in which the allocation takes place can be added by placing
special macros in the client code. A notification of a deletion
consists of the address of the memory being freed.</p>
<p>Elephant is not intended to ship in production code. It is
intended as a debugging aid. Elephant's functionality can be
removed simply by relinking without the Elephant static library.
All other code can remain in place.</p>
<p>Elephant comes with a complete, Aeryn (<a href=
"http://www.paulgrenyer.co.uk/aeryn" target=
"_top">http://www.paulgrenyer.co.uk/aeryn</a>) based test suite to
test that it behaves correctly on any given platform.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e46" id="d0e46"></a>Where Can I Get
Elephant?</h2>
</div>
<p>Elephant is available for download from: <a href=
"http://www.paulgrenyer.dyndns.org/elephant/" target=
"_top">http://www.paulgrenyer.dyndns.org/elephant/</a></p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e53" id="d0e53"></a>What Do I Need
To Build Elephant?</h2>
</div>
<p>Elephant uses up-to-date C++ techniques (including member
function templates using the Aeryn unit tests), as well as some
classes based on parts of Andrei Alexandrescu's Loki library
(<a href="http://sourceforge.net/projects/loki-lib/" target=
"_top">http://sourceforge.net/projects/loki-lib/</a>) and therefore
requires a modern compiler. It has been tested on, and provides
make files or project files for the following compilers:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Microsoft Visual C++ 7.1</p>
</li>
<li>
<p>MinGW 3.2.3</p>
</li>
<li>
<p>GNU G++ 3.2.3</p>
</li>
</ul>
</div>
<p>It may be possible to get Elephant to compile on Microsoft
Visual C++ 6.0.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e73" id="d0e73"></a>How Do I Build
Elephant?</h2>
</div>
<p>Elephant consists of a group of headers and a static library.
The full source is supplied with Elephant and the static library
must be built. Building the elephant static library couldn't be
easier:</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e78" id="d0e78"></a>Microsoft Visual
C++ 7.1</h3>
</div>
<p>To build the Elephant library, unit tests and the (test)
supporting Aeryn library with Microsoft Visual C++ 7.1, simply open
the Elephant solution located in the top level Elephant directory
and select Build Solution from the Build menu.</p>
<p>To run the unit tests right click on the <tt class=
"literal">TestClient</tt> project in the Solution Explorer and
select Set as StartUp Project, then select Start Without Debugging
from the Debug menu. This should give you the following output:</p>
<pre class="screen">
Aeryn 0.4.0 beta (c) Paul Grenyer 2004
http://www.paulgrenyer.co.uk/aeryn
--------------------------------------
Ran 21 tests, 21 Passed, 0 Failed.
Press any key to continue
</pre></div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e90" id="d0e90"></a>MinGW</h3>
</div>
<p>To build the Elephant library, unit tests and the (test)
supporting Aeryn library with MinGW open a command prompt and
navigate to the top level Elephant directory. Making sure that the
MinGW bin directory is in your path, type:</p>
<p><span><b class="command">mingw32-make</b></span></p>
<p>To run the unit tests type the following:</p>
<p><span><b class="command">bin\TestClient.exe</b></span></p>
<p>This should give you the following output:</p>
<pre class="screen">
Aeryn 0.4.0 beta (c) Paul Grenyer 2004
http://www.paulgrenyer.co.uk/aeryn
--------------------------------------
Ran 21 tests, 21 Passed, 0 Failed.
</pre>
<p>For <span><b class="command">mingw32-make clean</b></span> to
work correctly the rm tool from MSYS or cygwin must also be in your
path.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e112" id="d0e112"></a>g++</h3>
</div>
<p>To build the Elephant library, unit tests and the (test)
supporting Aeryn library with g++ open a command prompt and
navigate to the top level Elephant directory. Checking that g++ and
make are both installed correctly, type:</p>
<p><span><b class="command">make</b></span></p>
<p>To run the unit tests type the following:</p>
<p><span><b class="command">bin/TestClient.exe</b></span></p>
<p>This should give you the following output:</p>
<pre class="screen">
Aeryn 0.4.0 beta (c) Paul Grenyer 2004
http://www.paulgrenyer.co.uk/aeryn
--------------------------------------
Ran 21 tests, 21 Passed, 0 Failed.
</pre>
<p>The current version of Elephant was tested with g++ 3.2.3 on Red
Hat Linux ES 3.0. If any of the tests fail on your platform
Elephant may not work as expected. If you do have tests that fail,
please send me the complete Aeryn output along with details of your
g++ version and operating system.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e131" id="d0e131"></a>How Do I Set
Up My Environment To Use Elephant?</h2>
</div>
<p>Before you can use Elephant, the Elephant static library must be
built (see previous section):</p>
<div class="variablelist">
<dl>
<dt><span class="term">Microsoft Visual C++ 7.1</span></dt>
<dd>
<p><tt class="filename">Elephant_debug.lib</tt> (debug) <tt class=
"filename">Elephant.lib</tt> (release)</p>
</dd>
<dt><span class="term">MinGW</span></dt>
<dd>
<p><tt class="filename">libelephant.a</tt></p>
</dd>
<dt><span class="term">g++</span></dt>
<dd>
<p><tt class="filename">libelephant.a</tt></p>
</dd>
</dl>
</div>
<p>Regardless of which compiler or platform is used the Elephant
library is places in the bin directory which a subdirectory of the
Elephant top level directory.</p>
<p>Your environment also needs to have access to the Elephant
include directory which is a subdirectory of the top level Elephant
directory. The actual Elephant include files are stored in further
subdirectories called elephant and tools (tools is a subdirectory
of elephant). This is so that Elephant include files can be
identified from other include files which might share the same
name. For example:</p>
<pre class="programlisting">
#include &lt;elephant/newdelete.h&gt;
</pre>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e168" id="d0e168"></a>Microsoft Visual
C++ 7.1</h3>
</div>
<p>Once you have created a solution containing the project which is
going to use Elephant to monitor memory usage, you are ready to add
Elephant to your environment.</p>
<p>There are at least two ways to add the Elephant static library
to your solution:</p>
<div class="variablelist">
<dl>
<dt><span class="term">Method 1: Add the ElephantLib project to the
solution.</span></dt>
<dd>
<p>This method has the advantage that the <tt class=
"filename">ElephantLib</tt> project is included in a rebuild
all.</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Right click the solution name in Solution Explorer and select
Add Existing Project from the Add menu item.</p>
</li>
<li>
<p>Navigate to the <tt class="filename">ElephantLib</tt> directory
which is a subdirectory of the Elephant top level directory.</p>
</li>
<li>
<p>Select <tt class="filename">ElephantLib.vcproj</tt> and click
open. (This will add the Elephant library project to your
solution.)</p>
</li>
<li>
<p>Right click your project and select Project Dependencies from
the menu. Then put a tick in the ElephantLib box and click Ok.</p>
</li>
</ol>
</div>
</dd>
<dt><span class="term">Method 2: Add the Elephant static library
directly to the project.</span></dt>
<dd>
<div class="orderedlist">
<ol type="1">
<li>
<p>Right click your project and select properties.</p>
</li>
<li>
<p>Set the Configuration drop-down box to All Configurations.</p>
</li>
<li>
<p>Select the Linker folder and then the General item in the tree
view.</p>
</li>
<li>
<p>Enter the path to the Elephant static libraries (<tt class=
"filename">Elephant\bin</tt>) into the Additional Library
Directories box.</p>
</li>
<li>
<p>Set the Configuration drop-down box to debug.</p>
</li>
<li>
<p>Select the Input item from the Linker folder in the tree
view.</p>
</li>
<li>
<p>Enter <tt class="filename">Elephant_debug.lib</tt> into the
Additional Dependencies box.</p>
</li>
<li>
<p>Set the Configuration drop-down box to release.</p>
</li>
<li>
<p>Enter <tt class="filename">Elephant.lib</tt> into the Additional
Dependencies box</p>
</li>
<li>
<p>Click Ok</p>
</li>
</ol>
</div>
<p>To make the Elephant headers available to your project in your
solution follow these steps:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Right click your project and select properties.</p>
</li>
<li>
<p>Set the Configuration drop-down box to All Configurations.</p>
</li>
<li>
<p>Select the C/C++ folder and then the General item in the tree
view.</p>
</li>
<li>
<p>Enter the path to the Elephant include files (<tt class=
"filename">Elephant\include</tt>) into the Additional Include
Directories box.</p>
</li>
<li>
<p>Click Ok.</p>
</li>
</ol>
</div>
</dd>
</dl>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e269" id="d0e269"></a>MinGW &amp;
g++</h3>
</div>
<p>This description of configuring MinGW and g++ to link to
Elephant assumes that you are using a make file to build your
project. Of course this is not the only way.</p>
<p>To link Elephant to your executable (or shared library etc) two
extra parameters need to be added to your link command: the path to
the Elephant static library, preceded by <tt class=
"literal">-L</tt> and the name of library, preceded by <tt class=
"literal">-l</tt>. For example:</p>
<p><span><b class="command">g++ myproj.o -LElephant/bin -lelephant
myproj</b></span></p>
<p>The Elephant include files must be made available to every
invocation of g++ that builds a source (cpp) file that includes,
directly or indirectly, an Elephant include file. This is done by
adding a single parameter, which consists of the path to the
Elephant include directory preceded by <tt class="literal">-I</tt>.
For example:</p>
<p><span><b class="command">g++ -c -o myproj.o myproj.cpp
-IElephant/include</b></span></p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e293" id="d0e293"></a>How Do I Use
Elephant In My Program?</h2>
</div>
<p>Assuming that you have built the Elephant static library and
integrated it into your environment (see previous two sections) you
are now ready to use Elephant in your program.</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e298" id="d0e298"></a><tt class=
"methodname">operator new</tt> and <tt class="methodname">operator
delete</tt></h3>
</div>
<p>The custom implementations of <tt class="methodname">operator
new</tt> and <tt class="methodname">operator delete</tt> are the
key to Elephant's ability to monitor memory. There are overloads
for the normal and array versions with corresponding no throw
versions.</p>
<p>To use the Elephant's custom <tt class="methodname">new</tt> and
<tt class="methodname">delete</tt> operators simply include the
<tt class="filename">newdelete.h</tt> header in your program. For
example:</p>
<pre class="programlisting">
#include &lt;elephant/newdelete.h&gt;
int main() {
  return 0;
}
</pre>
<p>It only needs to be included once, although multiple inclusions
will not do any harm.</p>
<p>Every time a call is made to new or delete the Elephant operator
overloads will register the call with the Elephant memory monitor.
The Elephant memory monitor is observerable and you can register
one of the provided observers or write your own to react to the
allocations and de-allocations.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e330" id="d0e330"></a>Example 1:
Observing and Reporting a Memory Leak</h3>
</div>
<p>Let's start of with a simple example of a memory leak:</p>
<pre class="programlisting">
#include &lt;elephant/newdelete.h&gt;
class SomethingToAllocate {};
int main() {
  SomethingToAllocate* p
                   = new SomethingToAllocate;
  return 0;
}
</pre>
<p>This program will compile and run and you will see absolutely no
indication of the memory leak. In order to detect the memory leak
you need the leak detector class, <tt class=
"classname">LeakDetector</tt>. The leak detector class is an
observer of the memory monitor, so you need to register and
unregister it as an observer:</p>
<pre class="programlisting">
#include &lt;elephant/newdelete.h&gt;
#include &lt;elephant/memorymonitorholder.h&gt;
#include &lt;elephant/leakdetector.h&gt;
class SomethingToAllocate {};

int main() {
  using namespace elephant;
  LeakDetector leakDetector;
  // Register leak detector with memory monitor.
  MemoryMonitorHolder().Instance().AddObserver(
                                   &amp;leakDetector);
  SomethingToAllocate* p = new SomethingToAllocate;
  // Unregister leak detector with memory monitor.
  MemoryMonitorHolder().Instance().RemoveObserver(
                                   &amp;leakDetector);
  return 0;
}
</pre>
<p>To use the memory monitor and the leak detector you need to
include the appropriate header files as shown. Running this program
will still not indicate that there is a memory leak. To indicate
the memory leak you need to interrogate the <tt class=
"classname">LeakDetector</tt> instance. For example:</p>
<pre class="programlisting">
#include &lt;elephant/newdelete.h&gt;
#include &lt;elephant/memorymonitorholder.h&gt;
#include &lt;elephant/leakdetector.h&gt;
#include &lt;cassert&gt;
class SomethingToAllocate {};

int main() {
  using namespace elephant;
  LeakDetector leakDetector;
  // Register leak detector with memory monitor.
  MemoryMonitorHolder().Instance().AddObserver(
                                  &amp;leakDetector);
  SomethingToAllocate* p = new SomethingToAllocate;
  // Unregister leak detector with memory monitor.
  MemoryMonitorHolder().Instance().RemoveObserver(
                                   &amp;leakDetector);
  assert(!leakDetector.IsLeak());
  return 0;
}
</pre>
<p>The <tt class="function">assert</tt> (which required the
<tt class="filename">cassert</tt> header as shown) will indicate
that a memory leak has occurred. This particular method of
indicating a memory leak isn't particularly useful. The next step
is to print the memory address and the size of the leak:</p>
<pre class="programlisting">
#include &lt;elephant/newdelete.h&gt;
#include &lt;elephant/memorymonitorholder.h&gt;
#include &lt;elephant/leakdetector.h&gt;
#include &lt;elephant/leakdisplayfunc.h&gt;
#include &lt;algorithm&gt;
class SomethingToAllocate {};

int main() {
  using namespace elephant;
  LeakDetector leakDetector;
  // Register leak detector with memory monitor.
  MemoryMonitorHolder().Instance().AddObserver(
                                   &amp;leakDetector);
  SomethingToAllocate* p = new SomethingToAllocate;
  // Unregister leak detector with memory monitor.
  MemoryMonitorHolder().Instance().RemoveObserver(
                                   &amp;leakDetector);
  // Display the details of the leak.
  LeakDisplayFunc leakDisplay(std::cout);
  std::for_each(leakDetector.begin(),
                leakDetector.end(), leakDisplay);
  return 0;
}
</pre>
<p>The <tt class="classname">LeakDisplayFunc</tt> class constructor
takes a reference to an output stream and has a function operator
that can be used, as shown, to the write memory leak information to
the stream. As <tt class="classname">LeakDisplayFunc</tt> uses an
output stream it is possible that memory will be allocated and not
freed until the end of <tt class="function">main</tt>. This is why
the leak detector must be unregistered before the memory leak
information is displayed. Otherwise the output stream allocation
will appear as a further memory leak. One way to avoid having to
unregister the <tt class="classname">LeakDetector</tt> is to write
your own function object that displays the memory leak information
without allocating memory using <tt class="methodname">new</tt>.
For example using <tt class="function">printf</tt>. The output from
this program should be as follows, although the address will be a
different value:</p>
<pre class="screen">
Address:        00320B70
Size:           1
</pre></div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e383" id="d0e383"></a>Example 2:
Recording Line and Filename of Allocation</h3>
</div>
<p>In the previous example the memory leak was displayed as a
memory address and a size. This can be useful in finding a memory
leak, but not as usual as tracking the exact site of the
allocation. Elephant can do this by introducing a special macro
into every translation unit where this type of tracking is needed.
The macro is called ELEPHANTNEW and can be included anywhere in the
translation unit. The following code shows how the macro would be
added to example 1:</p>
<pre class="programlisting">
#include &lt;elephant/newdelete.h&gt;
#include &lt;elephant/memorymonitorholder.h&gt;
#include &lt;elephant/leakdetector.h&gt;
#include &lt;elephant/leakdisplayfunc.h&gt;
#include &lt;algorithm&gt;

#define new ELEPHANTNEW

class SomethingToAllocate {};
int main() {
  ...
}
</pre>
<p>The output should now look something like this:</p>
<pre class="screen">
Address:        00322878
Size:           1
Line:           22
Function:       main
File:           c:\...\example2\main.cpp
</pre>
<p>Some compilers, such as Microsoft Visual C++ 7.1 will show a
fully qualified function name and a complete a full file path.
Other compilers, such as g++ and MinGW will show only the local
function name and file name without the full path. For example:</p>
<pre class="screen">
Address:        0x3d24f0
Size:           1
Line:           23
File:           main.cpp
</pre></div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e398" id="d0e398"></a>Example 3: Using
the Maximum Memory Observer</h3>
</div>
<p>The other memory observer supplied with Elephant, <tt class=
"classname">MaxMemoryObserver</tt>, is for measuring the maximum
amount of memory used at anyone time by an application. Its use is
very similar to that of <tt class=
"classname">LeakDetector</tt>:</p>
<pre class="programlisting">
#include &lt;elephant/newdelete.h&gt;
#include &lt;elephant/memorymonitorholder.h&gt;
#include &lt;elephant/maxmemoryobserver.h&gt;
class SomethingToAllocate {};

int main() {
  using namespace elephant;
  MaxMemoryObserver maxMemory;
  // Register max memory observer with memory monitor.
  MemoryMonitorHolder().Instance().AddObserver(
                                        &amp;maxMemory);
  SomethingToAllocate *p1
                     = new SomethingToAllocate[100];
  delete[] p1;
  SomethingToAllocate *p2
                     = new SomethingToAllocate[50];
  delete[] p2;
  // Unregister max memory observer.
  MemoryMonitorHolder().Instance().RemoveObserver(
                                        &amp;maxMemory);

  // Display the max memory usage
  std::cout &lt;&lt; &quot;Max memory usage: &quot; 
            &lt;&lt; static_cast&lt;unsigned long&gt;(
                              maxMemory.MaxMemory())
            &lt;&lt; &quot; bytes\n&quot;;
  return 0;
}
</pre>
<p>The output from this simple (not very exception safe) example is
as follows:</p>
<pre class="screen">
Max memory usage: 100 bytes
</pre>
<p>The size of <tt class="classname">SomethingToAllocate</tt> is 1
byte. During the execution of the program a total of 150 <tt class=
"classname">SomethingToAllocate</tt> instances are created and
destroyed. However, the program only has up to 100 instances
allocated at any one time. Therefore the maximum amount of memory
used by the program is 100 bytes.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e423" id="d0e423"></a>Example 4:
Writing a Custom Memory Observer (Part 1)</h3>
</div>
<p>Elephant can be used for more than just detecting memory leaks
and the maximum memory used by a program. Elephant can be used to
monitor any characteristic of new and delete based memory usage via
custom memory observers. Custom memory observers are simple to
create. All that is required is the implementation of the following
interface:</p>
<pre class="programlisting">
namespace elephant {
  class IMemoryObserver {
  protected:
    IMemoryObserver();
  public:
    virtual ~IMemoryObserver() = 0;
    virtual void OnAllocate(void* p, size_t size,
                 size_t line, const char* file) = 0;
    virtual void OnFree(void* p) = 0;
  private:
    IMemoryObserver(const IMemoryObserver&amp;);
    IMemoryObserver&amp; operator=(
                            const IMemoryObserver&amp;);
  };
}
</pre>
<p>All that needs to be done to implement the interface is to
inherit from it and override the <tt class=
"methodname">OnAllocate</tt> and <tt class="methodname">OnFree</tt>
pure virtual member functions. The <tt class=
"methodname">OnAllocate</tt> function has the following
arguments:</p>
<p><i class="parameter"><tt>p</tt></i> - A pointer to the memory
that has been allocated. This is useful for getting the
address.</p>
<p><i class="parameter"><tt>size</tt></i> - The size of the memory
that has been allocated.</p>
<p><i class="parameter"><tt>line</tt></i> - The line number on
which the memory was allocated. This is 0 unless the ELEPHANTNEW
macro has been used correctly.</p>
<p><i class="parameter"><tt>char</tt></i> - The file in which the
memory was allocated. This is an empty string unless the
ELEPHANTNEW macro has been used correctly.</p>
<p>The <tt class="methodname">OnFree</tt> function has the
following argument:</p>
<p><i class="parameter"><tt>p</tt></i> - A pointer to the memory
that has been allocated. This is useful for getting the
address.</p>
<p>The default constructor of the interface is protected to show
that the class should be inherited from. The copy constructor and
assignment operator are private to prevent attempts to copy the
interface or its subclasses (unless the subclasses define their own
copy constructor and assignment operator) and the destructor is
virtual to ensure proper destruction should a dynamically allocated
subclass by destroyed via a pointer to the interface.</p>
<p>The example below is of a simple custom observer which records
the total memory allocated by a program during its lifetime:</p>
<pre class="programlisting">
class TotalMemoryobserver : public elephant::IMemoryObserver {
private:
  size_t totalMemory_;
public:
  TotalMemoryobserver()
      : totalMemory_(0) {}
  virtual void OnAllocate(void* p, size_t size,
                   size_t line, const char* file) {
    totalMemory_ += size;
  }
  virtual void OnFree(void* p) {}
  size_t TotalMemory() const {
    return totalMemory_;
  }
}
</pre>
<p>The <tt class="methodname">OnAllocate</tt> override is used to
accumulate the size of every allocation. The other parameters are
ignored as they are not needed. The <tt class=
"methodname">OnFree</tt> function does nothing as we are not
interested in de-allocations. In, for example, the leak detector,
the value of p passed to <tt class="methodname">OnFree</tt> is used
to match against a previous value of p passed to <tt class=
"methodname">OnAllocate</tt> to show that the memory has been
deleted.</p>
<p>Replacing <tt class="classname">MaxMemoryObserver</tt>, from the
previous example, with <tt class=
"classname">TotalMemoryobserver</tt> and making a couple of other
minor changes:</p>
<pre class="programlisting">
int main() {
  using namespace elephant;
  TotalMemoryobserver totalMemory;
  // Register max memory observer with memory monitor.
  MemoryMonitorHolder().Instance().AddObserver(
                                      &amp;totalMemory);
  SomethingToAllocate *p1
                    = new SomethingToAllocate[100];
  delete[] p1;
  SomethingToAllocate *p2
                    = new SomethingToAllocate[50];
  delete[] p2;
  // Unregister max memory observer.
  MemoryMonitorHolder().Instance().RemoveObserver(
                                      &amp;totalMemory);
  // Display the max memory usage
  std::cout &lt;&lt; &quot;Total memory usage: &quot; 
            &lt;&lt; static_cast&lt;unsigned long&gt;(
                         totalMemory.TotalMemory())
            &lt;&lt; &quot; bytes\n&quot;;
  return 0;
}
</pre>
<p>gives the following output, which correctly indicates the total
memory used by the program:</p>
<pre class="screen">
Total memory usage: 150 bytes
</pre></div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e500" id="d0e500"></a>Example 5:
Writing a Custom Memory Observer (Part 2)</h3>
</div>
<p>Sometimes you want to store information about allocations and
de-allocations in a container within a custom memory observer.
Containers do of course allocate memory in order to contain. This
could lead to erroneous memory usage observations and, in a worst
case scenario, infinite recursion.</p>
<p>The simple answer is to use a container that uses <tt class=
"function">malloc</tt> and <tt class="function">free</tt> instead
of <tt class="methodname">new</tt> and <tt class=
"methodname">delete</tt>. Or, to be more precise, a container that
uses an allocator that allocates with <tt class=
"function">malloc</tt> and <tt class="function">free</tt> instead
of <tt class="methodname">new</tt> and <tt class=
"methodname">delete</tt>. Elephant comes with just such an
allocator, called <tt class="function">malloc_allocator</tt>, which
can be used with any of the C++ standard library containers. It
should be used as follows:</p>
<pre class="programlisting">
#include &lt;elephant/tools/mallocallocator.h&gt;
#include &lt;vector&gt;
...
std::vector&lt;size_t,
      elephant::tools::malloc_allocator&lt;size_t&gt; &gt;
      allocStore;
</pre>
<p>Naturally a <tt class="literal">typedef</tt> can make life a lot
easier.</p>
<p>The following example shows a custom memory observer that uses a
container with the malloc_allocator to store two lists of the
addresses, allocations and de-allocations:</p>
<pre class="programlisting">
#include &lt;elephant/newdelete.h&gt;
#include &lt;elephant/memorymonitorholder.h&gt;
#include &lt;elephant/imemoryobserver.h&gt;
#include &lt;elephant/tools/mallocallocator.h&gt;
#include &lt;vector&gt;

class AllocationMemoryobserver : public
                        elephant::IMemoryObserver {
private:
  typedef std::vector&lt;void*,
        elephant::tools::malloc_allocator&lt;void*&gt; &gt;
        MAllocContainer;
  typedef MAllocContainer::const_iterator
        const_iterator;
  MAllocContainer allocations_;
  MAllocContainer deallocations_;

  void Print(const MAllocContainer&amp; cont,
             std::ostream&amp; out) {

    const_iterator current = cont.begin();
    const_iterator end  = cont.end();
    for(; current != end; ++current) {
      out &lt;&lt; &quot;\t&quot; &lt;&lt; (*current) &lt;&lt; &quot;\n&quot;;
    }
    out &lt;&lt; &quot;\n&quot;;
  }
public:
  AllocationMemoryobserver() : allocations_(),
                               deallocations_() {}
  virtual void OnAllocate(void* p, size_t size,
                   size_t line, const char* file) {
    allocations_.push_back(p);
  }
  virtual void OnFree(void* p) {
    deallocations_.push_back(p);
  }
  void PrintAllocations(std::ostream&amp; out) {
    out &lt;&lt; &quot;Allocations:\n&quot;;
    Print(allocations_, out);
  }
  void PrintDeallocations(std::ostream&amp; out) {
    out &lt;&lt; &quot;Deallocations:\n&quot;;
    Print(deallocations_, out);
  }
};

class SomethingToAllocate {};

int main() {
  using namespace elephant;
  AllocationMemoryobserver allocationObserver;
  // Register max memory observer with memory monitor.
  MemoryMonitorHolder().Instance().AddObserver(
                               &amp;allocationObserver);
  SomethingToAllocate *p1
                     = new SomethingToAllocate[100];
  SomethingToAllocate *p2
                     = new SomethingToAllocate[50];
  delete[] p2;
  delete[] p1;
  // Unregister max memory observer.
  MemoryMonitorHolder().Instance().RemoveObserver(
                               &amp;allocationObserver);
  allocationObserver.PrintAllocations(std::cout);
  allocationObserver.PrintDeallocations(std::cout);
  return 0;
}
</pre>
<p>The output from this example is as follows:</p>
<pre class="screen">
Allocations:
        00322850
        00322910
Deallocations:
        00322910
        00322850
</pre>
<p>If <tt class="function">malloc_allocator</tt> is replaced by the
default allocator, there is no output, not even an error message,
with both Microsoft Visual C++ and MinGW.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e554" id="d0e554"></a>Elephant and
Threading</h2>
</div>
<p>Elephant has not yet been tested in a multithreaded
environment.</p>
<p>The use of the <tt class="classname">Mutex</tt> class and its
various implementations are based on previously known working
examples.</p>
<p><span class="bold"><b>Offers to test Elephant in a multithreaded
environment will be gratefully accepted.</b></span></p>
<p>By default, Elephant is not thread safe. The <tt class=
"filename">mutex.h</tt> header file is included in a number of
places and the <tt class="classname">Mutex</tt> class, along with
the <tt class="classname">Guard</tt> class (for exception safety)
is used to protect those parts of the library that may cause
problems if accessed by two threads at the same time.</p>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e578" id="d0e578"></a>Elephant
Mutexes</h3>
</div>
<p>If you open the mutex.h header file, you will see it looks like
this:</p>
<pre class="programlisting">
#ifndef ELEPHANT_TOOLS_MUTEX_H
#define ELEPHANT_TOOLS_MUTEX_H
#include &lt;elephant/tools/nullmutex.h&gt;
//#include &lt;elephant/tools/boostmutex.h&gt;
//#include &lt;elephant/tools/win32mutex.h&gt;
#endif // ELEPHANT_TOOLS_MUTEX_H
</pre>
<p>There are three types of mutex supplied with Elephant:</p>
<div class="variablelist">
<dl>
<dt><span class="term">Null Mutex</span></dt>
<dd>
<p>An empty mutex class intended for use in single threaded
programs so that no performance is lost creating, entering or
leaving an unnecessary mutex.</p>
</dd>
<dt><span class="term">Win32 Mutex</span></dt>
<dd>
<p>Implemented using the Win32 API for use with Windows compilers
only.</p>
</dd>
<dt><span class="term">Boost Mutex</span></dt>
<dd>
<p>A mutex implemented using <tt class=
"classname">boost::mutex</tt> (<a href=
"http://boost.org/libs/thread/doc/mutex_concept.html" target=
"_top">http://boost.org/libs/thread/doc/mutex_concept.html</a>).</p>
</dd>
</dl>
</div>
<p>The Null Mutex is used by default. To use one of the other
mutexes simply include its header file in <tt class=
"filename">mutex.h</tt> instead of <tt class=
"filename">nullmutex.h</tt> and rebuild (a rebuild all is
recommended).</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e620" id="d0e620"></a>Custom
Mutexes</h3>
</div>
<p>A custom mutex can be written simply by implementing the
following class in its own header file and including it in mutex.h
instead of the other mutex header files:</p>
<pre class="programlisting">
namespace elephant {
  namespace tools {
    class Mutex {
    public:
      Mutex() {}
      ~Mutex() {}
      void Enter() const {}
      void Leave() const {}
    private:
      Mutex(const Mutex&amp;);
      Mutex&amp; operator=(const Mutex&amp;);
    };
  }
}
</pre>
<p>Note: As the <tt class="methodname">Enter</tt> and <tt class=
"methodname">Leave</tt> member functions are <tt class=
"literal">const</tt>, you may need to make the object that holds
the current state of the mutex <tt class=
"literal">mutable</tt>.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e641" id="d0e641"></a>Where
Next?</h2>
</div>
<p>This is the very first beta release of Elephant. Therefore I
expect I, and hopefully other people, will find plenty of bugs or
new features that should be implemented, over the coming
months.</p>
<p>So far, planned for future releases:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Threading testing and unit tests.</p>
</li>
<li>
<p>Black and white allocation lists</p>
</li>
<li>
<p>Client memory tracking</p>
</li>
</ul>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
