<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Steven Engelhardt &#187; STL</title>
	<atom:link href="http://www.deez.info/sengelha/category/programming/cplusplus/stl/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.deez.info/sengelha</link>
	<description>A financial industry software developer's thoughts and insights</description>
	<lastBuildDate>Tue, 13 Apr 2010 18:28:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>STL objects and module boundaries</title>
		<link>http://www.deez.info/sengelha/2008/01/04/stl-objects-and-module-boundaries/</link>
		<comments>http://www.deez.info/sengelha/2008/01/04/stl-objects-and-module-boundaries/#comments</comments>
		<pubDate>Fri, 04 Jan 2008 22:27:15 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[STL]]></category>
		<category><![CDATA[Win32]]></category>

		<guid isPermaLink="false">http://www.deez.info/sengelha/blog/2008/01/04/stl-objects-and-module-boundaries/</guid>
		<description><![CDATA[Let&#8217;s say you have the following function:



void AppendChar&#40;std::string&#38; s, char ch&#41;


&#123;


&#160; &#160; s += ch;


&#125;



What happens if this function is exported as an ordinal function from a DLL (not an inlined piece of code inside a header) and you call it from an EXE?

It works most of the time.  When it doesn&#8217;t, it corrupts [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say you have the following function:</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw4">void</span> AppendChar<span class="br0">&#40;</span>std::<span class="me2">string</span>&amp; s, <span class="kw4">char</span> ch<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; s += ch;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>What happens if this function is exported as an ordinal function from a DLL (not an inlined piece of code inside a header) and you call it from an EXE?<br />
<span id="more-5438"></span><br />
It works most of the time.  When it doesn&#8217;t, it corrupts your heap and causes a spectacular mess.</p>
<p>In Windows you must <a href="http://blogs.msdn.com/oldnewthing/archive/2006/09/15/755966.aspx">free memory with the same allocator that allocated it</a>. However, your EXE may not share the same allocator as the DLL.  Perhaps the two modules are linked against different versions of libc, or perhaps one of the modules is using a static version of libc.  If your EXE and DLL do <em>not </em>share an allocator <em>and</em> if AppendChar resizes the string s, you will almost certainly cause a heap corruption.</p>
<p>The STL performs a lot of reallocations behind the scenes for you; this is one of its major benefits.  Unfortunately, if you are writing a general-purpose DLL these behind-the-scene allocations are deadly.  You cannot know or dictate what version of libc your clients will use.</p>
<p>Therefore, I reiterate my <a href="http://www.deez.info/sengelha/2006/03/03/c-stl-dlls-and-buggy-optimizations/">previous recommendation</a>:</p>
<blockquote><p>Avoid passing STL objects as parameters to DLLs.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.deez.info/sengelha/2008/01/04/stl-objects-and-module-boundaries/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>STL Map Use</title>
		<link>http://www.deez.info/sengelha/2007/01/25/stl-map-use/</link>
		<comments>http://www.deez.info/sengelha/2007/01/25/stl-map-use/#comments</comments>
		<pubDate>Thu, 25 Jan 2007 15:43:31 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[STL]]></category>

		<guid isPermaLink="false">http://www.deez.info/sengelha/blog/2007/01/25/stl-map-use/</guid>
		<description><![CDATA[
What&#8217;s wrong with the following code?




template&#60;typename T1, typename T2&#62;


struct my_pair


&#123;


&#160; &#160; typedef T1 first_type;


&#160; &#160; typedef T2 second_type;


&#160;


&#160; &#160; my_pair&#40;&#41; : first&#40;T1&#40;&#41;&#41;, second&#40;T2&#40;&#41;&#41; &#123;&#125;


&#160; &#160; my_pair&#40;const T1&#38; v1, const T2&#38; v2&#41; : first&#40;v1&#41;, second&#40;v2&#41; &#123;&#125;


&#160;


&#160; &#160; T1 first;


&#160; &#160; T2 second;


&#125;;


&#160;


template&#60;typename T1, typename T2&#62;


inline bool operator&#60;


&#160; &#160; &#40;


&#160; &#160; const my_pair&#60;T1, T2&#62;&#38; x,


&#160; &#160; const [...]]]></description>
			<content:encoded><![CDATA[<p>
What&#8217;s wrong with the following code?
</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">template&lt;typename T1, <span class="kw2">typename</span> T2&gt;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw4">struct</span> my_pair</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw4">typedef</span> T1 first_type;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw4">typedef</span> T2 second_type;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; my_pair<span class="br0">&#40;</span><span class="br0">&#41;</span> : first<span class="br0">&#40;</span>T1<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>, second<span class="br0">&#40;</span>T2<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; my_pair<span class="br0">&#40;</span><span class="kw4">const</span> T1&amp; v1, <span class="kw4">const</span> T2&amp; v2<span class="br0">&#41;</span> : first<span class="br0">&#40;</span>v1<span class="br0">&#41;</span>, second<span class="br0">&#40;</span>v2<span class="br0">&#41;</span> <span class="br0">&#123;</span><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; T1 first;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; T2 second;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">template&lt;typename T1, <span class="kw2">typename</span> T2&gt;</div>
</li>
<li class="li2">
<div class="de2"><span class="kw2">inline</span> <span class="kw4">bool</span> operator&lt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw4">const</span> my_pair&lt;T1, T2&gt;&amp; x,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw4">const</span> my_pair&lt;T1, T2&gt;&amp; y</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <span class="br0">&#40;</span>x.<span class="me1">first</span> &lt; y.<span class="me1">first</span> || x.<span class="me1">second</span> &lt; y.<span class="me1">second</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw4">void</span> f<span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw4">typedef</span> my_pair&lt;&#8230;, &#8230;&gt; key_type;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw4">typedef</span> &#8230; <span class="me1">value_type</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw4">typedef</span> std::<span class="me2">map</span>&lt;key_type, value_type&gt; map_type;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; map_type map;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// Use map</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p><span id="more-5395"></span></p>
<p>
Answer: <code>my_pair</code> cannot be used as a key for a STL <code>map</code> because the <code>operator&lt;</code> violates the rule of <a href="http://www.sgi.com/tech/stl/StrictWeakOrdering.html">strict weak ordering</a>.   More specifically, the operator is not antisymmetric.  Consider the following:
</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw4">typedef</span> my_pair&lt;int, int&gt; P;</div>
</li>
<li class="li1">
<div class="de1">P p1<span class="br0">&#40;</span><span class="nu0">3</span>, <span class="nu0">5</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">P p2<span class="br0">&#40;</span><span class="nu0">2</span>, <span class="nu0">6</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>
Both <code>p1 &lt; p2</code> <i>and</i> <code>p2 &lt; p1</code> evaluate to <i>true</i>.
</p>
<p>
If you use <code>my_pair</code> as a key into a <code>map</code> you will not get any compiler errors or warnings but you will likely see some bizarre runtime behavior.  For example, keys which were successfully <code>insert()</code>ed may not be able to be found using <code>find()</code>.
</p>
<p>
A correct version of <code>operator&lt;</code> (which places minimal burden on <code>T1</code> and <code>T2</code> &mdash; they are only required to implement <code>operator&lt;</code>) is:
</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1">template&lt;typename T1, <span class="kw2">typename</span> T2&gt;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">inline</span> <span class="kw4">bool</span> operator&lt;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw4">const</span> my_pair&lt;T1, T2&gt;&amp; x,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw4">const</span> my_pair&lt;T1, T2&gt;&amp; y</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; x.<span class="me1">first</span> &lt; y.<span class="me1">first</span> ||</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>!<span class="br0">&#40;</span>y.<span class="me1">first</span> &lt; x.<span class="me1">first</span><span class="br0">&#41;</span> &amp;&amp; x.<span class="me1">second</span> &lt; y.<span class="me1">second</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.deez.info/sengelha/2007/01/25/stl-map-use/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>STL Vector Use</title>
		<link>http://www.deez.info/sengelha/2007/01/23/stl-vector-use/</link>
		<comments>http://www.deez.info/sengelha/2007/01/23/stl-vector-use/#comments</comments>
		<pubDate>Wed, 24 Jan 2007 04:15:18 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[STL]]></category>

		<guid isPermaLink="false">http://www.deez.info/sengelha/blog/2007/01/23/stl-vector-use/</guid>
		<description><![CDATA[
I recently wrote a piece of code that looked something like the following:




static const int NUM_TOTAL_VALUES = &#8230;;


typedef &#8230; T;


&#160;


// Create vec and reserve NUM_TOTAL_VALUES spaces for later insertion


std::vector&#60;T&#62; vec&#40;NUM_TOTAL_VALUES&#41;;


&#160;


// Insert values into vec


for &#40;int i = 0; i != NUM_TOTAL_VALUES; ++i&#41;


&#160; &#160; vec.push_back&#40;&#8230;&#41;;


&#160;


// vec should now have NUM_TOTAL_VALUES values in it (but doesn&#8217;t!)




What&#8217;s wrong [...]]]></description>
			<content:encoded><![CDATA[<p>
I recently wrote a piece of code that looked something like the following:
</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw4">static</span> <span class="kw4">const</span> <span class="kw4">int</span> NUM_TOTAL_VALUES = &#8230;;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw4">typedef</span> &#8230; <span class="me1">T</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// Create vec and reserve NUM_TOTAL_VALUES spaces for later insertion</span></div>
</li>
<li class="li2">
<div class="de2">std::<span class="me2">vector</span>&lt;T&gt; vec<span class="br0">&#40;</span>NUM_TOTAL_VALUES<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// Insert values into vec</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">int</span> i = <span class="nu0">0</span>; i != NUM_TOTAL_VALUES; ++i<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; vec.<span class="me1">push_back</span><span class="br0">&#40;</span>&#8230;<span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// vec should now have NUM_TOTAL_VALUES values in it (but doesn&#8217;t!)</span></div>
</li>
</ol>
</div>
<p>
What&#8217;s wrong with this code?
</p>
<p><span id="more-5394"></span></p>
<p>
The constructor <code>vector(size_type _Count);</code> does more than just allocate enough space to store <code>_Count</code> items &#8212; it also inserts <code>_Count</code> (default constructed) items into the vector.  To reserve space without actually inserting values, use <code>reserve()</code>:
</p>
<div class="dean_ch" style="white-space: nowrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw4">static</span> <span class="kw4">const</span> <span class="kw4">int</span> NUM_TOTAL_VALUES = &#8230;;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw4">typedef</span> &#8230; <span class="me1">T</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">std::<span class="me2">vector</span>&lt;T&gt; vec;</div>
</li>
<li class="li2">
<div class="de2">vec.<span class="me1">reserve</span><span class="br0">&#40;</span>NUM_TOTAL_VALUES<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw4">int</span> i = <span class="nu0">0</span>; i != NUM_TOTAL_VALUES; ++i<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; vec.<span class="me1">push_back</span><span class="br0">&#40;</span>&#8230;<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li2">
<div class="de2"><span class="co1">// vec now has NUM_TOTAL_VALUES values in it, as intended.</span></div>
</li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.deez.info/sengelha/2007/01/23/stl-vector-use/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Simple STL Map Tricks</title>
		<link>http://www.deez.info/sengelha/2006/07/12/simple-stl-map-tricks/</link>
		<comments>http://www.deez.info/sengelha/2006/07/12/simple-stl-map-tricks/#comments</comments>
		<pubDate>Wed, 12 Jul 2006 12:00:17 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[STL]]></category>

		<guid isPermaLink="false">http://www.deez.info/sengelha/blog/2006/07/12/simple-stl-map-tricks/</guid>
		<description><![CDATA[
Let&#8217;s say you have two STL std::maps with identical types, and you want to copy all the elements from one to the other.  The easiest way to do this is to use map::insert():


typedef std::map&#60;key_type, value_type&#62; map_t;

map_t map1;
map_t map2;

// Copy all elements from map1 to map2
map2.insert(map1.begin(), map1.end());


Alternatively, you could use the STL std::copy algorithm:


// Copy [...]]]></description>
			<content:encoded><![CDATA[<p>
Let&#8217;s say you have two <a href="http://www.sgi.com/tech/stl/">STL</a> <a href="http://www.sgi.com/tech/stl/Map.html"><code>std::map</code></a>s with identical types, and you want to copy all the elements from one to the other.  The easiest way to do this is to use <code>map::insert()</code>:
</p>
<pre>
typedef std::map&lt;<i>key_type</i>, <i>value_type</i>&gt; map_t;

map_t map1;
map_t map2;

// Copy all elements from map1 to map2
map2.insert(map1.begin(), map1.end());
</pre>
<p>
Alternatively, you could use the STL <a href="http://www.sgi.com/tech/stl/copy.html"><code>std::copy</code></a> algorithm:
</p>
<pre>
// Copy all elements from map1 to map2.
std::copy(map1.begin(), map1.end(), std::inserter(map2, map2.begin()));
</pre>
<p>
Both methods&#8217; performance should be an amortized O(n) because they insert records in sorted order and use the <a href="http://msdn2.microsoft.com/en-us/library/81ac0zkz.aspx">hinting form of <code>map::insert</code></a>.
</p>
<p>
Note that because both methods ultimately call <code>map::insert</code> they will not overwrite a preexisting key&#8217;s associated value.  In other words, if <code>map1</code> has the value <i>V1</i> associated with key <i>K</i> and <code>map2</code> the value <i>V2</i> associated with the same key <i>K</i>, <i>V2</i> will remain in <code>map2</code> after the copy operation.
</p>
<p>
Let&#8217;s say you want to perform the copy but have <code>map1</code>&#8217;s values overwrite <code>map2</code>&#8217;s for identical keys.  The first way to solve this problem that entered my mind was to write my own <a href="http://www.sgi.com/tech/stl/OutputIterator.html">OutputIterator</a> which performs an overwriting assignment and pass it to <code>std::copy</code>.  However, there&#8217;s a far simpler approach.  You can copy <i><code>map2</code></i>&#8217;s values into <i><code>map1</code></i>, relying on the fact that <code>map2</code>&#8217;s values <i>won&#8217;t</i> overwrite <code>map1</code>&#8217;s, and then swap the results:
</p>
<pre>
map1.insert(map2.begin(), map2.end());
map2.swap(map1);
</pre>
<p>
Thanks, Sam, for helping me figure all this out.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.deez.info/sengelha/2006/07/12/simple-stl-map-tricks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++, STL, DLLs, and Buggy Optimizations</title>
		<link>http://www.deez.info/sengelha/2006/03/03/c-stl-dlls-and-buggy-optimizations/</link>
		<comments>http://www.deez.info/sengelha/2006/03/03/c-stl-dlls-and-buggy-optimizations/#comments</comments>
		<pubDate>Fri, 03 Mar 2006 16:44:15 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[STL]]></category>

		<guid isPermaLink="false">http://www.deez.info/sengelha/blog/2006/03/03/c-stl-dlls-and-buggy-optimizations/</guid>
		<description><![CDATA[
Recently a bug in the STL implementation that comes with Visual C++ 6.0 was brought to my attention.  Consider the following function:


typedef std::map&#60;std::string, std::string&#62; map_t;

void f(const map_t&#38; map)
{
    for (map_t::const_iterator iter = map.begin();
         iter != map.end();
        [...]]]></description>
			<content:encoded><![CDATA[<p>
Recently a bug in the STL implementation that comes with Visual C++ 6.0 was brought to my attention.  Consider the following function:
</p>
<pre>
typedef std::map&lt;std::string, std::string&gt; map_t;

void f(const map_t&amp; map)
{
    for (map_t::const_iterator iter = map.begin();
         iter != map.end();
         ++iter)
    {
    }
}
</pre>
<p>
For Visual C++ 6.0, if you call <code>f()</code> from within the same EXE or DLL, it works fine, but <i>if calling <code>f()</code> requires you to cross an EXE or DLL barrier, it will fail</i>.
</p>
<p>
After some debugging, I figured out that this bug is because Visual C++ 6.0&#8217;s implementation of <code>std::map</code>, which stores data in a tree structure internally, uses a class static variable to represent a NULL tree node.  After putting <code>f()</code> in a separate DLL, the <code>std::map</code> class static value gets initialized to one value in the EXE (on a run on my machine, <code>0x002f1000</code>) and another value in the DLL (on a run on my machine, <code>0x003127c0</code>).  The <code>++iter</code> line in the DLL leads to a loop which terminates when it encounters a node it thinks is NULL (<code>0x003127c0</code>).  However, as the NULL node was set by the EXE, it has the value <code>0x002f1000</code>, so the loop within the DLL walks off the tree and crashes.
</p>
<p>
Per <a href="http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q172/3/96.ASP&amp;NoWebContent=1">Microsoft Knowledge Base Article 172396: You may experience an access violation when you access an STL object through a pointer or reference in a different DLL or EXE</a>, this is a problem that&#8217;s fairly endemic across all of VC++ 6.0 when using STL objects across DLL/EXE barriers.  The reason is Microsoft&#8217;s STL implementation used class static variables in a number of places to try to avoid storing multiple copies of the same information, but they did not anticipate this DLL-related problem.  By the way, this bug is reportedly fixed in Visual C++ 7.
</p>
<p>
The <a href="http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q172/3/96.ASP&amp;NoWebContent=1">KB article</a> has a number of suggested workarounds, but I don&#8217;t like any of them.  <a href="http://www.dinkumware.com/">Dinkumware</a>, who wrote the Visual C++ 6.0 STL library, has provided a <code>xtree</code> header replacement which fixes the bug by making the value of NULL tree nodes a member of the class rather than a class static variable as part of their <a href="http://www.dinkumware.com/vc_fixes.html">Fixes for Library Bugs in VC++ V5.0/V6.0</a> page, but I don&#8217;t like the idea of using third-party compiler header replacements.
</p>
<p>
My recommendation is to avoid passing STL objects as parameters to DLLs.  I also suggest being very careful about using class static variables in your own code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.deez.info/sengelha/2006/03/03/c-stl-dlls-and-buggy-optimizations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Write Functions Which Take Iterators, Not Collections</title>
		<link>http://www.deez.info/sengelha/2005/09/05/write-functions-which-take-iterators-not-collections/</link>
		<comments>http://www.deez.info/sengelha/2005/09/05/write-functions-which-take-iterators-not-collections/#comments</comments>
		<pubDate>Mon, 05 Sep 2005 21:03:23 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[STL]]></category>

		<guid isPermaLink="false">http://www.deez.info/sengelha/blog/?p=5273</guid>
		<description><![CDATA[
If my experience is typical, this is a very common construct:


ReturnType Function
    (
    const std::vector&#60;T&#62;&#38; container
    )
{
    typedef std::vector&#60;T&#62;::const_iterator iterator_t;
    for (iterator_t iter = container.begin();
         iter != container.end();
     [...]]]></description>
			<content:encoded><![CDATA[<p>
If my experience is typical, this is a very common construct:
</p>
<pre>
ReturnType Function
    (
    const std::vector&lt;T&gt;&amp; container
    )
{
    typedef std::vector&lt;T&gt;::const_iterator iterator_t;
    for (iterator_t iter = container.begin();
         iter != container.end();
         ++iter) {
        // Work with *iter
    }
}
</pre>
<p>
The problem with this construct is that you have forced a container choice upon the user of your function.  Slightly better, and basically your only choice when interoping with C, is this:
</p>
<pre>
ReturnType Function
    (
    T* array,
    int numItems
    )
{
    for (int i = 0; i &lt; numItems; ++i) {
        // Work with array[numItems]
    }

    // Or perhaps:
    // for (T* pT = array; pT != array + numItems; ++pT) {
    //     Work with *pT
    // }
}
</pre>
<p>
With the above construct you can pass in any container which uses contiguous storage, such as an array or a <code>std::vector</code> (yes, <a href="http://www.parashift.com/c++-faq-lite/containers.html#faq-34.3"><code>std::vector</code>s <i>are</i> guaranteed to store the data contiguously</a>).  Passing a <code>std::vector</code> to the above function looks like:
</p>
<pre>
std::vector&lt;T&gt; v;
ReturnType ret = Function(v.empty() ? 0 : &amp;v[0], v.size());
</pre>
<p>
However, in C++ its far better to do as the STL does and write your function to accept iterators, as in:
</p>
<pre>
template &lt;class InputIterator&gt;
ReturnType Function
    (
    InputIterator first,
    InputIterator last
    )
{
    for (InputIterator iter = first; iter != last; ++iter) {
        // Work with *iter
    }
}
</pre>
<p>
By using this construct, you allow vast usage flexibility.  Try to limit yourself to <a href="http://www.sgi.com/tech/stl/InputIterator.html">input iterator</a> expressions on <code>first</code> and <code>last</code> (basically preincrement, dereference, and comparison) to minimize the requirements the <code>InputIterator</code> class must fulfill.
</p>
<p>
Most (all?) STL containers can pass their contents to <code>Function()</code> by using the containers&#8217; <code>begin()</code> and <code>end()</code> functions, as in:
</p>
<pre>
std::vector&lt;T&gt; v;
ReturnType ret = Function(v.begin(), v.end());
</pre>
<p>
As C pointers are random-access iterators, you can pass arrays to <code>Function()</code> as follows:
</p>
<pre>
const int arraySize = ...;
T array[arraySize];

ReturnType ret = Function(array, array + arraySize);
</pre>
<p>
By the way, this lesson also applies to C#: prefer writing functions which accept <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemcollectionsienumerableclasstopic.asp"><code>IEnumerable</code></a>s rather than collections such as arrays.  (In C# 2.0, you should be able to regain the lost typesafety by accepting <code>IEnumerable&lt;T&gt;</code>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.deez.info/sengelha/2005/09/05/write-functions-which-take-iterators-not-collections/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Prefer Iteration To Indexing</title>
		<link>http://www.deez.info/sengelha/2005/09/02/prefer-iteration-to-indexing/</link>
		<comments>http://www.deez.info/sengelha/2005/09/02/prefer-iteration-to-indexing/#comments</comments>
		<pubDate>Fri, 02 Sep 2005 18:03:35 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[STL]]></category>

		<guid isPermaLink="false">http://www.deez.info/sengelha/blog/?p=5252</guid>
		<description><![CDATA[
I&#8217;ve seen the following STL construct countless times:


std::vector&#60;T&#62; container;

for (int i = 0; i &#60; container.size(); ++i) {
    // Work with container[i]
}


Unless otherwise necessary, it is better to use an STL iterator because it enables you to more easily change the underlying container.  You can isolate the code changes required to [...]]]></description>
			<content:encoded><![CDATA[<p>
I&#8217;ve seen the following STL construct countless times:
</p>
<pre>
std::vector&lt;T&gt; container;

for (int i = 0; i &lt; container.size(); ++i) {
    // Work with container[i]
}
</pre>
<p>
Unless otherwise necessary, it is better to use an STL iterator because it enables you to more easily change the underlying container.  You can isolate the code changes required to one line by using <code>typedef</code>, as in:
</p>
<pre>
typedef std::vector&lt;T&gt; container_t;
container_t container;

// Or ::const_iterator as necessary
for (container_t::iterator iter = container.begin();
     iter != container.end();
     ++iter) {
    // Work with *iter
}
</pre>
<p>
Note that I wrote <code>iter != container.end()</code> as opposed to <code>iter &lt; container.end()</code>.  The former only requires an <a href="http://www.sgi.com/tech/stl/InputIterator.html">input iterator</a>, while the latter requires a <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">random access iterator</a>&mdash;a more complicated iterator type supported by fewer STL containers.
</p>
<p>
Also note that I wrote <code>++iter</code> as opposed to <code>iter++</code>.  In general, you should prefer the former expression because it is always at least as efficient as the latter, and often times more so.
</p>
<p>
Of course, for a code block like the one above, you really should consider using the STL algorithm <a href="http://www.sgi.com/tech/stl/for_each.html"><code>for_each</code></a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.deez.info/sengelha/2005/09/02/prefer-iteration-to-indexing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
