<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2303980609371615468</id><updated>2011-12-12T12:25:47.319-08:00</updated><title type='text'>Dusty Pixels and Polygons</title><subtitle type='html'>Things I've learned, relearned, discovered, or just think ought to be written down.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bradgrantham.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2303980609371615468/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bradgrantham.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Brad Grantham</name><uri>http://www.blogger.com/profile/08393124011533390909</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2303980609371615468.post-5756251996771168356</id><published>2010-03-06T14:13:00.001-08:00</published><updated>2010-03-06T14:13:21.361-08:00</updated><title type='text'></title><content type='html'>&lt;div style="text-align:center"&gt;&lt;b&gt;&lt;font size="5"&gt;Fixing Sony SZ volume and brightness buttons - ACPI&lt;/font&gt;&lt;/b&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;For a couple of years, my Sony SZ hasn&amp;#39;t had working volume or brightness buttons under Ubuntu.&amp;nbsp; If I remember correctly, they worked fine on Ubuntu 6.10, but since then they haven&amp;#39;t worked right.&lt;br&gt;&lt;br&gt;The volume buttons issue double events, so it&amp;#39;s impossible to fine-tune volume.&amp;nbsp; The mute button mutes and then instantly unmutes.&lt;br&gt;&lt;br&gt;Since I&amp;#39;ve upgraded to 64-bit Ubuntu, the screen brightness buttons haven&amp;#39;t worked, either.&lt;br&gt;&lt;h1&gt;Introduction&lt;/h1&gt;ACPI (a power-management system about which I know little) issues interrupts in response to events like pressing a hardware button (for example &amp;quot;S1&amp;quot; on the Sony SZ), or a key combination (Fn-F3 is supposed to reduce volume), or power events, among other things.&lt;br&gt;&lt;br&gt;You can watch the incoming ACPI event stream with the &lt;font face="courier new"&gt;acpi_listen&lt;/font&gt; command.&amp;nbsp; An event like pressing Fn-F3 prints out:&lt;br&gt;&lt;blockquote style="font-family:Courier New"&gt;sony/hotkey SPIC 00000001 0000000e&lt;br&gt;sony/hotkey SPIC 00000001 0000003b&lt;br&gt;&lt;/blockquote&gt;&lt;div&gt;(0e is when F3 is pressed down, 3b is when it&amp;#39;s released.)&amp;nbsp; The Linux &lt;font face="courier new"&gt;acpid&lt;/font&gt; daemon reads event descriptions from &lt;font face="courier new"&gt;/etc/acpi/events/&lt;/font&gt;, then executes the &amp;quot;action&amp;quot; attribute for files that match an incoming event.&amp;nbsp; For example, here&amp;#39;s the contents of &lt;font face="courier new"&gt;/etc/acpi/events/sony-volume-down&lt;/font&gt;:&lt;br&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;font face="courier new"&gt;# /etc/acpi/events/sony-volume-down&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt;event=sony/hotkey SPIC 00000001 0000000e&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt;action=/etc/acpi/voldownbtn.sh&lt;/font&gt;&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;So when &amp;quot;&lt;font face="courier new"&gt;SPIC 00000001 0000000e&lt;/font&gt;&amp;quot; comes across the wire, acpid runs &lt;font face="courier new"&gt;/etc/acpi/voldownbtn.sh&lt;/font&gt;.&amp;nbsp; Here&amp;#39;s the *unpatched* contents of &lt;font face="courier new"&gt;/etc/acpi/voldownbtn.sh&lt;/font&gt;:&lt;br&gt;&lt;blockquote style="font-family:Courier New"&gt;#!/bin/sh&lt;br&gt;&lt;br&gt;test -f /usr/share/acpi-support/key-constants || exit 0&lt;br&gt;&lt;br&gt;. /usr/share/acpi-support/key-constants&lt;br&gt;acpi_fakekey $KEY_VOLUMEDOWN&lt;br&gt;&lt;/blockquote&gt;&lt;h1&gt;Fixing the audio buttons Fn-F2, Fn-F3, Fn-F4&lt;/h1&gt;I don&amp;#39;t know why, but the volume down event is issued once by &lt;i&gt;something in the system&lt;/i&gt;, then issued &lt;i&gt;again&lt;/i&gt; by &lt;font face="courier new"&gt;acpi_fakekey&lt;/font&gt;.&amp;nbsp; For some reason the volume controls lower or raise the volume, then issue the Sony volume control, which issues an ACPI event, which lowers or raises them &lt;i&gt;again&lt;/i&gt;.&amp;nbsp; I commented out the call to &lt;font face="courier new"&gt;acpi_fakekey&lt;/font&gt; in &lt;font face="courier new"&gt;/etc/acpi/voldownbtn.sh&lt;/font&gt;, &lt;font face="courier new"&gt;/etc/acpi/volupbtn.sh&lt;/font&gt;, and &lt;font face="courier new"&gt;/etc/acpi/mutebtn.sh&lt;/font&gt; and now they correctly only increase or decrease one notch, including the on-screen display.&lt;br&gt;&lt;h1&gt;Fixing the brightness buttons, Fn-F5, Fn-F6&lt;/h1&gt;For whatever reason, the 64-bit installation of Ubuntu 9.04 does not have support for the Sony brightness buttons.&lt;br&gt;&lt;br&gt;Put &lt;a href="http://plunk.org/%7Egrantham/sony-brightness-up" id="kx8l" style="font-family:Courier New" title="sony-brightness-up"&gt;sony-brightness-up&lt;/a&gt; and &lt;a href="http://plunk.org/%7Egrantham/sony-brightness-down" id="ff75" style="font-family:Courier New" title="sony-brightness-down"&gt;sony-brightness-down&lt;/a&gt; in &lt;font face="courier new"&gt;/etc/acpi/events&lt;/font&gt;.&amp;nbsp; These two are from my previous 32-bit installation.&lt;br&gt;&lt;br&gt;Put &lt;a href="http://plunk.org/%7Egrantham/sonybright.sh" id="c021" style="font-family:Courier New" title="sonybright.sh"&gt;sonybright.sh&lt;/a&gt; in &lt;font face="courier new"&gt;/etc/acpi&lt;/font&gt;.&amp;nbsp; This one is from my 32-bit installation but I edited it to make it work better with a package called &lt;i&gt;smartdimmer&lt;/i&gt;.&lt;br&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;font face="courier new"&gt;sudo apt-get install smartdimmer&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;Finally,&amp;nbsp; in order to reload the event descriptions from /etc/acpi/events:&lt;br&gt;&lt;blockquote&gt;&lt;font face="courier new"&gt;sudo killall -HUP acpid&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2303980609371615468-5756251996771168356?l=bradgrantham.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bradgrantham.blogspot.com/feeds/5756251996771168356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2303980609371615468&amp;postID=5756251996771168356' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2303980609371615468/posts/default/5756251996771168356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2303980609371615468/posts/default/5756251996771168356'/><link rel='alternate' type='text/html' href='http://bradgrantham.blogspot.com/2010/03/fixing-sony-sz-volume-and-brightness.html' title=''/><author><name>Brad Grantham</name><uri>http://www.blogger.com/profile/08393124011533390909</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2303980609371615468.post-2977864850067802163</id><published>2010-03-06T13:00:00.001-08:00</published><updated>2010-03-08T16:01:52.813-08:00</updated><title type='text'></title><content type='html'>&lt;br&gt;&lt;h1 style="text-align:center"&gt;&lt;a id="My_Experience_Transitioning_to" name="My_Experience_Transitioning_to"&gt;&lt;/a&gt;My Experience Transitioning to Boost::shared_ptr&lt;/h1&gt;&lt;br&gt;&lt;div style="text-align:center"&gt;Brad Grantham, brad.grantham@gmail.com&lt;br&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="writely-toc" id="WritelyTableOfContents" toctype="upper-roman+lower-roman"&gt;&lt;ol class="writely-toc-upper-roman"&gt;&lt;li&gt;&lt;a href="#My_Experience_Transitioning_to" target="_self"&gt;My Experience Transitioning to Boost::shared_ptr&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Motivation_48049111594083427_5_21350501811558598" target="_self"&gt;Motivation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Transitioning_to_Boost_shared_" target="_self"&gt;Transitioning to Boost::shared_ptr&lt;/a&gt;&lt;/li&gt;&lt;ol class="writely-toc-lower-roman writely-toc-subheading" style="margin-left:0pt"&gt;&lt;li&gt;&lt;a href="#Headers_21975103627630876_0221_7706180239971545" target="_self"&gt;Headers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Consistent_Typedef_for_Conveni" target="_self"&gt;Consistent Typedef for Convenience&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Boost_shared_ptr_does_and_does" target="_self"&gt;Sometimes Boost::shared_ptr behaves like a pointer.&lt;/a&gt;&lt;/li&gt;&lt;ol class="writely-toc-lower-roman writely-toc-subheading" style="margin-left:0pt"&gt;&lt;li&gt;&lt;a href="#Members_Still_Work_Like_They_U" target="_self"&gt;Members Still Work Like They Used To&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#_Assigning_shared_ptrs_Works_A" target="_self"&gt;Assigning shared_ptrs Works As Expected&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;&lt;a href="#Sometimes_Boost_sharedptr_does_5617769539153961" target="_self"&gt;Sometimes Boost::shared_ptr does not behave like a pointer&lt;/a&gt;&lt;/li&gt;&lt;ol class="writely-toc-lower-roman writely-toc-subheading" style="margin-left:0pt"&gt;&lt;li&gt;&lt;a href="#Checking_for_NULL_654346578405" target="_self"&gt;Checking for NULL&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#A_New_Idiom_for_new_4043391752" target="_self"&gt;A New Idiom for &amp;quot;new&amp;quot;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Boost_shared_ptr_is_Constructe" target="_self"&gt;Boost::shared_ptr is Constructed Empty By Default&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Clearing_a_Boost_shared_ptr_Li" target="_self"&gt;Clearing a Boost::shared_ptr Like Assigning NULL to a Pointer&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Use_of_this_Pointer_7953273896" target="_self"&gt;Use of &amp;quot;this&amp;quot; Pointer&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Using_typeid_5555476335337439_" target="_self"&gt;Using &amp;quot;typeid&amp;quot;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Where_I_Was_Using_dynamic_cast_45379234056885265" target="_self"&gt;Where I Was Using &amp;quot;dynamic_cast&amp;quot;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;li&gt;&lt;a href="#Results_7088811322456197_32484" target="_self"&gt;Results&lt;/a&gt;&lt;/li&gt;&lt;ol class="writely-toc-lower-roman writely-toc-subheading" style="margin-left:0pt"&gt;&lt;li&gt;&lt;a href="#Memory_Management_277308622525_9794898864571792" target="_self"&gt;Memory Management&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#Performance_46618515546667005_" target="_self"&gt;Performance&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;&lt;a href="#Conclusions_18555530298004508_" target="_self"&gt;Conclusions&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br&gt;&lt;h1&gt;&lt;a id="Motivation_48049111594083427_5_21350501811558598" name="Motivation_48049111594083427_5_21350501811558598"&gt;&lt;/a&gt;Motivation&lt;/h1&gt;I recently moved from C++ pointers using new and delete to Boost shared_ptr.&amp;nbsp; I spent two days reading up on shared_ptr, then spent about four hours modifying around 3400 lines of C++.&lt;br&gt;&lt;br&gt;My primary reason for using Boost:shared_ptr is to prevent leaks.&amp;nbsp; If a shared_ptr owns a pointer to an object, that shared_ptr can be passed around and copied, and when the last instance of shared_ptr pointing to an object goes out of scope, the object is deleted.&lt;br&gt;&lt;br&gt;In my application, I have a large directed graph of spatial transformations with geometric objects at the leaves.&amp;nbsp; I would like to delete the root of the graph and have all of the things to which it points be automatically freed, if no other pointers to them would exist.&amp;nbsp; I can&amp;#39;t just delete the children of a parent node because more than one parent node might point to a given child node.&amp;nbsp; (For example, I might have one geometric model of a tire, but have it referenced in two different locations in the model of a bicycle.)&amp;nbsp; So somehow I have to keep track of all the parents pointing to a child, and when there are none left, delete the child.&amp;nbsp; Boost::shared_ptr does that.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;class Shape&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // other Shape class stuff&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; typedef boost::shared_ptr&amp;lt;Shape&amp;gt; sptr;&lt;br&gt;};&lt;br&gt;&lt;br&gt;class Bicycle&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Shape::sptr FrontTire;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Shape::sptr BackTire;&lt;br&gt;};&lt;br&gt;&lt;br&gt;void DrawABike(void)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Shape::sptr tire(new Tire());&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Shape::sptr bike(new Bicycle());&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; bike-&amp;gt;FrontTire = tire;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; bike-&amp;gt;BackTire = tire;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; draw(bike);&lt;br&gt;}&lt;br&gt;/*&lt;br&gt;At the end of this function, &amp;quot;bike&amp;quot; went out of scope and was deleted. &amp;quot;bike&amp;quot; had two shared_ptrs to &amp;quot;tire&amp;quot;; the first was cleared, and then, since the second was the only one left, it deleted &amp;quot;tire&amp;quot;.&lt;br&gt;*/&lt;br&gt;&lt;br&gt;void DrawABike(Shape::sptr&amp;amp; saved_tire)&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; Shape::sptr tire(new Tire());&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; Shape::sptr bike(new Bicycle());&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; saved_tire = tire;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; bike-&amp;gt;FrontTire = tire;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; bike-&amp;gt;BackTire = tire;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; draw(bike);&lt;br&gt; }&lt;br&gt;/*&lt;br&gt;At the end of this function, &amp;quot;bike&amp;quot; went out of scope and was deleted.&amp;nbsp; &amp;quot;bike&amp;quot; had two shared_ptrs to &amp;quot;tire&amp;quot;, but the caller to this function was also given a shared_ptr through &amp;quot;saved_tire&amp;quot;, so tire is not deleted.&amp;nbsp; When the shared_ptr passed in by reference in &amp;quot;saved_tire&amp;quot; goes out of scope (or is cleared), if there are no other shared_ptrs to &amp;quot;tire&amp;quot;, then &amp;quot;tire&amp;quot; will be deleted.&lt;br&gt;*/&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;Setting a shared_ptr which already has a pointer can delete the old object if there are no other shared_ptrs pointing to it.&amp;nbsp; It also takes care of the occasional case where an application assigns a shared_ptr the same pointer it already has.&lt;br&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;shared_ptr&amp;lt;Image&amp;gt; GetChecker();&lt;br&gt;shared_ptr&amp;lt;Image&amp;gt; img(new Image(diffuseTextureMapName));&lt;br&gt;if(img-&amp;gt;GetWidth() == -1){&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Failed to load file from diffuseTextureMapName.&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /* this line deletes the Image we new&amp;#39;d above, when it replaces it with the Image passed back from GetChecker(). */&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; img = GetChecker();&lt;br&gt;}&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;Going out of scope without passing off a pointer deletes the object, as would be expected.&lt;br&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;vector&amp;lt;Shape::sptr&amp;gt; shapes;&lt;br&gt;//...&lt;br&gt;Shape::sptr sphere(new Sphere(center, radius, material));&lt;br&gt;&lt;br&gt;if(some_kind_of_test)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; shapes.push_back(sphere);&lt;br&gt;&lt;br&gt;return true;&lt;br&gt;// If sphere was not added to shapes, then it is deleted here&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;Classes containing shared_ptrs don&amp;#39;t have to initialize the pointer to NULL in their constructor because the shared_ptr constructor initializes itself to empty.&lt;br&gt;&lt;h1&gt;&lt;a id="Transitioning_to_Boost_shared_" name="Transitioning_to_Boost_shared_"&gt;&lt;/a&gt;Transitioning to Boost::shared_ptr&lt;/h1&gt;Here are some pointer cases I had to handle in my code and what I did with them and some hints and tips.&lt;br&gt;&lt;h2&gt;&lt;a id="Headers_21975103627630876_0221_7706180239971545" name="Headers_21975103627630876_0221_7706180239971545"&gt;&lt;/a&gt;Headers&lt;/h2&gt;I added these two headers.&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;#include &amp;lt;boost/shared_ptr.hpp&amp;gt;&lt;br&gt; #include &amp;lt;boost/enable_shared_from_this.hpp&amp;gt;&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;a id="Consistent_Typedef_for_Conveni_8285000537137094" name="Consistent_Typedef_for_Conveni_8285000537137094"&gt;&lt;/a&gt;&lt;h2&gt;&lt;a id="Consistent_Typedef_for_Conveni" name="Consistent_Typedef_for_Conveni"&gt;&lt;/a&gt;Consistent typedef for Convenience&lt;/h2&gt;in any class T that I wanted to create and pass around between functions and modules, I added a typedef for &amp;quot;sptr.&amp;quot;&amp;nbsp; As an example:&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;class Shape {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Shape() { ... };&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; virtual ~Shape() { ... };&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; typedef boost::shared_ptr&amp;lt;T&amp;gt; sptr;&lt;br&gt;&lt;/div&gt;};&lt;br&gt;&lt;br&gt;Then, instead of:&lt;br&gt;&lt;br&gt;&lt;div style="font-family:Courier New;margin-left:40px"&gt;Shape *shape;&lt;br&gt;vector&amp;lt;Shape*&amp;gt; list;&lt;br&gt; const vector&amp;lt;Shape*&amp;gt; const_list;&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;I use:&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;&amp;nbsp;Shape::sptr shape;&lt;br&gt;&amp;nbsp;vector&amp;lt;Shape::sptr&amp;gt; list;&lt;br&gt;&amp;nbsp;const vector&amp;lt;Shape::sptr&amp;gt; const_list;&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;h2&gt;&lt;a id="Boost_shared_ptr_does_and_does" name="Boost_shared_ptr_does_and_does"&gt;&lt;/a&gt;Sometimes Boost::shared_ptr behaves like a pointer.&lt;/h2&gt;&lt;h3&gt;&lt;a id="Members_Still_Work_Like_They_U" name="Members_Still_Work_Like_They_U"&gt;&lt;/a&gt;Members Still Work Like They Used To&lt;/h3&gt;For that purpose, the pointer to member operator and member functions both work as if the shared_ptr was a real pointer.&amp;nbsp; If you were referencing member variables or calling a member function before, that still works.&lt;br&gt;&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;class Shape {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Shape() { ... };&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; virtual ~Shape() { ... };&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ...&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; typedef boost::shared_ptr&amp;lt;T&amp;gt; sptr;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; float Width;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; virtual void draw();&lt;br&gt;&lt;/div&gt;&lt;font face="courier new"&gt;};&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt; Shape::sptr shape(new Shape);&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt; // These still work as if &amp;quot;shape&amp;quot; was just a Shape*&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt; shape-&amp;gt;Width = 50.0f;&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt; shape-&amp;gt;draw();&lt;/font&gt;&lt;/blockquote&gt;&lt;h3&gt;Assigning shared_ptrs Works As Expected&lt;/h3&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;&amp;nbsp;// Shape *PopTree();&lt;br&gt;Shape *shape = PopTree();&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt; Changes to:&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;// Shape::sptr PopTree();&lt;br&gt;Shape::sptr shape = PopTree();&lt;br&gt; // reference to the Shape is handed from PopTree back to &amp;quot;shape&amp;quot;&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;h2&gt;&lt;a id="Sometimes_Boost_sharedptr_does_5617769539153961" name="Sometimes_Boost_sharedptr_does_5617769539153961"&gt;&lt;/a&gt;Sometimes Boost::shared_ptr does not behave like a pointer&lt;/h2&gt;I think it&amp;#39;s best to think of shared_ptr not really as a pointer but more as a class with a pointer in it.&amp;nbsp; Thus some obvious pointer operations have to change slightly.&lt;br&gt;&lt;h3&gt;&lt;a id="Checking_for_NULL_654346578405" name="Checking_for_NULL_654346578405"&gt;&lt;/a&gt;Checking for NULL&lt;/h3&gt;As one example, rather than checking for NULL, instead check for a boolean result, and let the bool member function check the pointer for you.&amp;nbsp; Instead of:&lt;br&gt;&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;if(shape != NULL) ...&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;I use:&lt;br&gt;&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;if(shape) ...&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;In the past, I had preferred the comparison to NULL in order to call out the nature of the variable as a pointer.&amp;nbsp; However, &amp;quot;if(shape)&amp;quot; would have worked fine for pointers as well, and I guess that is the way many developers check pointers for NULL.&lt;br&gt;&lt;h3&gt;&lt;a id="A_New_Idiom_for_new_4043391752" name="A_New_Idiom_for_new_4043391752"&gt;&lt;/a&gt;A New Idiom for &amp;quot;new&amp;quot;&lt;/h3&gt;In order to reduce the possibility of leaks, the Boost documentation recommends never holding a new object with a bare pointer.&amp;nbsp; Always use new as the initializer for a shared_ptr.&amp;nbsp; That is to say, avoid this:&lt;br&gt;&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;Shape *p = new Shape;&lt;br&gt;// some operations using &amp;quot;p&amp;quot;, e.g.&lt;br&gt;p-&amp;gt;draw();&lt;br&gt;Shape::sptr sp(p);&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;And instead do this:&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt; // some operations using &amp;quot;sp&amp;quot;&lt;br&gt; Shape::sptr sp(new Shape);&lt;br&gt;// do operations using &amp;quot;sp&amp;quot; instead&lt;br&gt;sp-&amp;gt;draw();&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;h3&gt;&lt;a id="Boost_shared_ptr_is_Constructe" name="Boost_shared_ptr_is_Constructe"&gt;&lt;/a&gt;Boost::shared_ptr is Constructed Empty By Default&lt;/h3&gt;It is okay to define a shared_ptr without an initializer.&amp;nbsp; For example, in code that used to look like this:&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;Shape *function()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Shape *p = NULL;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; // do things that might set ptr here, e.g.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(alright) {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; p = new Shape;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // stuff&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return p; // might return NULL&lt;br&gt;}&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;That code now looks like this:&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;Thingie::sptr function()&lt;br&gt;{&lt;br&gt;&lt;/div&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Shape::sptr sp;&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(alright) {&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sp = Shape::sptr(new Shape);&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // stuff&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return sp; // might return an empty shared_ptr&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt;}&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;&lt;h3&gt;&lt;a id="Clearing_a_Boost_shared_ptr_Li" name="Clearing_a_Boost_shared_ptr_Li"&gt;&lt;/a&gt;Clearing a Boost::shared_ptr Like Assigning NULL to a Pointer&lt;/h3&gt;I couldn&amp;#39;t find a literal that had the same effect on a shared_ptr as assigning NULL does to a pointer.&amp;nbsp; Instead, construct an empty shared_ptr, which will point to nothing on construction.&amp;nbsp; Assigning that to a shared_ptr clears the shared_ptr (so cast to bool will result in &amp;quot;false&amp;quot;) and will release and potentially delete the previous value.&amp;nbsp; So I changed this idiom: &lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;p = NULL;&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;To this:&lt;br&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;sp = Shape::sptr();&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;I could also have used the &amp;quot;reset()&amp;quot; member function (e.g. &amp;quot;sp.reset()&amp;quot;), but I think for the moment I like the idea of assignment because it is slightly more like the old assignment from NULL.&lt;br&gt;&lt;h3&gt;&lt;a id="Use_of_this_Pointer_7953273896" name="Use_of_this_Pointer_7953273896"&gt;&lt;/a&gt;Use of &amp;quot;this&amp;quot; Pointer&lt;/h3&gt;A more complicated issue is the use of &amp;quot;this&amp;quot; inside member functions.&amp;nbsp; In my code, I had used &amp;quot;this&amp;quot; for a few things.&amp;nbsp; A particular use case was for an object to insert itself into a list if it met certain criteria.&amp;nbsp; As an example:&lt;br&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;void Shape::Flatten(vector&amp;lt;Shape*&amp;gt;&amp;amp; flattened, const Matrix&amp;amp; fromObject)&lt;br&gt; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(fromObject.isidentity())&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; flattened.push_back(this);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; Group *g = new Group(fromObject);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; g-&amp;gt;_shapes.push_back(this);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; g-&amp;gt;makeBox();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; flattened.push_back(g);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;The problem is that an application cannot make a brand new shared_ptr from a pointer if a shared_ptr already exists.&amp;nbsp; That is to say, this does not work:&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;{&lt;br&gt;&lt;/div&gt;&lt;div style="font-family:Courier New"&gt;&lt;div style="margin-left:40px"&gt;Shape *shape = new Shape;&lt;br&gt;shared_ptr&amp;lt;Shape&amp;gt; shape1(shape);&lt;br&gt;shared_ptr&amp;lt;Shape&amp;gt; shape2(shape);&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;font face="courier new"&gt;}&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt;/*&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt;&amp;quot;shape1&amp;quot; and &amp;quot;shape2&amp;quot; do not know about each other, so when they go out of scope,&lt;/font&gt;&lt;font face="courier new"&gt;each will think they contain the only pointer to &amp;quot;shape&amp;quot;, and so each will try to delete&lt;/font&gt; &lt;font face="courier new"&gt;&amp;quot;shape&amp;quot;.&amp;nbsp; The second will delete deleted memory, which will likely cause a memory&lt;/font&gt; &lt;font face="courier new"&gt;protection error / segmentation fault.&lt;/font&gt;&lt;br style="font-family:Courier New"&gt;&lt;font face="courier new"&gt;*/&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;One can look at the implementation of shared_ptr to understand in detail why this doesn&amp;#39;t work, but a simple way to understand it is that shared_ptrs to a unique object have to know about each other in order to manage references correctly.&amp;nbsp; To let shared_ptrs know about each other, an application has to assign shared_ptrs to shared_ptrs.&amp;nbsp; This is one reason the idiom above of &amp;quot;shared_ptr&amp;lt;Thing&amp;gt; thing(new Thing);&amp;quot; is important to follow; let a bare pointer to a class exist for as brief a time as possible.&lt;br&gt;&lt;br&gt;Unfortunately, it is also a standard pattern to pass around &amp;quot;this&amp;quot; from inside member functions.&amp;nbsp; There will probably already be a shared_ptr created for an object at construction.&amp;nbsp; Later, when a method tries to use &amp;quot;this&amp;quot;, I would like my code to use a shared_ptr, but I can&amp;#39;t make a new shared_ptr for the reasons just mentioned.&amp;nbsp; For this we use the Boost::enable_shared_from_this template.&lt;br&gt;&lt;br&gt;First, we make sure our base class is derived from &amp;quot;enable_shared_from_this&amp;quot;:&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;class Shape : public enable_shared_from_this&amp;lt;Shape&amp;gt;&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Shape members and member functions&lt;br&gt;}&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;Then, where we would have used &amp;quot;this&amp;quot;, we use &amp;quot;shared_from_this()&amp;quot;:&lt;br&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;void Shape::Flatten(vector&amp;lt;Shape::sptr&amp;gt;&amp;amp; flattened, const Matrix&amp;amp; fromObject)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(fromObject.isidentity())&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; flattened.push_back(shared_from_this());&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Group::sptr g(new Group(fromObject));&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; g-&amp;gt;_shapes.push_back(shared_from_this());&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; g-&amp;gt;makeBox();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; flattened.push_back(g);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;h3&gt;&lt;a id="Using_typeid_5555476335337439_" name="Using_typeid_5555476335337439_"&gt;&lt;/a&gt;Using &amp;quot;typeid&amp;quot;&lt;/h3&gt;I use &amp;quot;typeid&amp;quot; in a few places in my code to figure out what to do with some objects.&amp;nbsp; As a hypothetical example, Triangle is derived from Shape, and Sphere is derived from Shape, and maybe I want to save Triangles in a separate data structure but not Spheres.&amp;nbsp; The &amp;quot;typeid&amp;quot; operator gives me the type_info for a pointer, and doesn&amp;#39;t know to check the pointer inside a shared_ptr.&amp;nbsp; I made a convenience template for myself that knows to do that.&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;template &amp;lt;class T&amp;gt;&lt;br&gt; const type_info&amp;amp; typeids(T sptr)&lt;br&gt; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return typeid(*sptr.get());&lt;br&gt; }&lt;br&gt;&lt;br&gt;// const vector&amp;lt;Shape::sptr&amp;gt; shapes;&lt;br&gt;vector&amp;lt;Shape::sptr&amp;gt; triangles_only;&lt;br&gt;const vector&amp;lt;Shape::sptr&amp;gt;::iterator it;&lt;br&gt;for(it = shapes.begin(); it != shapes.end(); it++) {&lt;br&gt;&amp;nbsp; &amp;nbsp; Shape::sptr s = *it;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(typeids(s) == typeid(Triangle)) {&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; triangles_only.push_back(s);&lt;br&gt;&amp;nbsp; &amp;nbsp; }&lt;br&gt;}&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;h3&gt;&lt;a id="Where_I_Was_Using_dynamic_cast_45379234056885265" name="Where_I_Was_Using_dynamic_cast_45379234056885265"&gt;&lt;/a&gt;Where I Was Using &amp;quot;dynamic_cast&amp;quot;&lt;/h3&gt;I pass around a &amp;quot;Shader::sptr&amp;quot; throughout the code.&amp;nbsp; &amp;quot;Shader&amp;quot; is an abstract base class and I have several subclasses that implement various functionality.&amp;nbsp; In one case, I was using &amp;quot;dynamic_cast&amp;quot; to determine if the Shader* actually pointed to a &amp;quot;PhongShader.&amp;quot;&amp;nbsp; Boost::shared_ptr provides a &amp;quot;dynamic_pointer_cast&amp;quot; template as a replacement to dynamic_cast that handles shared_ptrs.&amp;nbsp; Where I previously had this code:&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;Shader::sptr shader = loader.GetMaterial();&lt;br&gt;&lt;br&gt; PhongShader::sptr phong(boost::dynamic_pointer_cast&amp;lt;PhongShader&amp;gt;(shader));&lt;br&gt;&lt;br&gt; if(!phong) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; // this is defined only on class PhongShader.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; phong-&amp;gt;SetShininess();&lt;br&gt; }&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt; I now have this code:&lt;br&gt;&lt;blockquote&gt;&lt;div style="font-family:Courier New"&gt;Shader::sptr shader = loader.GetMaterial();&lt;br&gt; PhongShader::sptr phong(boost::dynamic_pointer_cast&amp;lt;PhongShader&amp;gt;(shader));&lt;br&gt; if(!phong) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; // this is defined only on class PhongShader.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; phong-&amp;gt;SetShininess();&lt;br&gt; }&lt;br&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;As an aside, using typeid() above opens me up to exceptions if my shared_ptr is NULL.&amp;nbsp; If I had instead used dynamic_pointer_cast, then I would not have an exception; rather the result of the cast would be empty.&amp;nbsp; I consider that to be safer and probably will transition to that.&lt;br&gt;&lt;h1&gt;&lt;a id="Results_7088811322456197_32484" name="Results_7088811322456197_32484"&gt;&lt;/a&gt;Results&lt;/h1&gt;&lt;h2&gt;&lt;a id="Memory_Management_277308622525_9794898864571792" name="Memory_Management_277308622525_9794898864571792"&gt;&lt;/a&gt;Memory Management&lt;/h2&gt;I use the &amp;quot;valgrind&amp;quot; tool on Linux to check for leaks.&amp;nbsp; In particular, I turn on &amp;quot;show-reachable&amp;quot; and &amp;quot;track-origins&amp;quot; and turn &amp;quot;leak-check&amp;quot; to full, like:&lt;br&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span class="il"&gt;&lt;font face="courier new"&gt;valgrind&lt;/font&gt;&lt;/span&gt;&lt;font face="courier new"&gt; --show-reachable=yes --track-origins=yes \&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; --leak-check=full &lt;/font&gt;&lt;font face="courier new"&gt;${COMMANDLINE}&lt;/font&gt;&lt;br&gt;&lt;/blockquote&gt;It&amp;#39;s surprising what other libraries leak memory.&amp;nbsp; But my tests show that using shared_ptr has allowed me to remove all leaks from my 3D models.&amp;nbsp; My top-level object references some 3D scene geometry objects using shared_ptr members, and those objects only reference other objects using shared_ptr.&amp;nbsp; When the top-level object is deleted, all of its associated data is deleted.&lt;br&gt;&lt;h2&gt;&lt;a id="Performance_46618515546667005_" name="Performance_46618515546667005_"&gt;&lt;/a&gt;Performance&lt;/h2&gt;My application is an interactive ray-tracer.&amp;nbsp; In most of my scenes, I experienced no significant drop in performance.&amp;nbsp; In one particular scene with no scene hierarchy and a large number of triangles in a single kd-tree, I measured a 2% drop in performance.&lt;br&gt;&lt;br&gt;In my data structure, each triangle has a shared_ptr to a shader, which is passed back if the triangle is hit by a ray.&amp;nbsp; In this particular model, there are 1.5 million triangles and only one shared shader.&amp;nbsp; Each triangle has a reference to this single shader.&amp;nbsp; I suspect the performance drop has to do with incrementing and decrementing reference counts in conjunction with locking from multiple threads, but I haven&amp;#39;t fully investigated that yet.&lt;br&gt;&lt;br&gt;My strategy going forward is to pass around only pointers in the inner loop, which may be executed in multiple threads.&amp;nbsp; One way to ensure that this approach doesn&amp;#39;t cause memory leaks or NULL pointer dereferences is to make shared_ptrs before kicking off threads to execute the inner loop, and release them at the end.&lt;br&gt;&lt;br&gt;Conceptually, the application then has sort of a &amp;quot;safe pointer section&amp;quot; where it allows the use of pointers but takes precautions beforehand to make it as safe as possible. Thus no objects can be unexpectedly deleted during the inner loop while a thread expects to work on them.&lt;br&gt;&lt;h3 style="margin-left:40px"&gt;Performance Addendum, Feburary 24th, 2010&lt;/h3&gt;&lt;p style="margin-left:40px"&gt;I have only performed a simple test to see how much performance I can gain back.&amp;nbsp; In my application, I built a test app configuration in which several million iterations of my inner loop would be fetching a pointer and then using it.&amp;nbsp; I edited my code to return only a pointer to the shader instead of a shared_ptr in the query that my inner loop calls&lt;br&gt;&lt;/p&gt;&lt;p style="margin-left:40px"&gt;&lt;br&gt;&lt;/p&gt;&lt;p style="margin-left:40px"&gt;The improvement is better than 5%.&amp;nbsp; A 5% gain might not seem like much, but for an interactive program it doesn&amp;#39;t take many 5% improvements before an application feels noticeably faster.&lt;br&gt;&lt;/p&gt;&lt;p style="margin-left:40px"&gt;&lt;br&gt;&lt;/p&gt;&lt;p style="margin-left:40px"&gt;My rule of thumb from now on will be to use shared_ptr whenever possible, but avoid passing them around tight loops.&lt;/p&gt;&lt;p style="margin-left:40px"&gt;&lt;br&gt;&lt;/p&gt;&lt;p style="margin-left:40px"&gt;In the future, I hope to add the code I mention above that will gather temporary copies of the shared_ptrs to shaders before entering the inner loop, so use of those pointers will be protected in my library&amp;#39;s inner loop.&lt;br&gt;&lt;/p&gt;&lt;h1&gt;&lt;a id="Conclusions_18555530298004508_" name="Conclusions_18555530298004508_"&gt;&lt;/a&gt;Conclusions&lt;/h1&gt;It takes a new mindset to use shared_ptr.&amp;nbsp; Some of the obvious ways pointers were used in my application needed to be transformed using new idioms.&amp;nbsp; But it&amp;#39;s clear that it essentially solved the memory management problem for me, with a minimal performance impact.&amp;nbsp; &lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2303980609371615468-2977864850067802163?l=bradgrantham.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bradgrantham.blogspot.com/feeds/2977864850067802163/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2303980609371615468&amp;postID=2977864850067802163' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2303980609371615468/posts/default/2977864850067802163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2303980609371615468/posts/default/2977864850067802163'/><link rel='alternate' type='text/html' href='http://bradgrantham.blogspot.com/2010/03/my-experience-transitioning-to_06.html' title=''/><author><name>Brad Grantham</name><uri>http://www.blogger.com/profile/08393124011533390909</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
