<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Amin's Blog</title>
  <id>urn:uuid:4ceb6a1d-425a-3b42-94ae-9e2802b4d840</id>
  <updated>2019-06-29T00:00:00Z</updated>
  <link href="http://www.amin.space/blog/" />
  <link href="http://www.amin.space/feed.xml" rel="self" />
  <author>
    <name></name>
  </author>
  <generator uri="https://github.com/ajdavis/lektor-atom" version="0.2">Lektor Atom Plugin</generator>
  <entry xml:base="http://www.amin.space/blog/latex_primer/">
    <title type="text">Primer for an Ancient Typesetting Language</title>
    <id>urn:uuid:379ae7f1-f45e-3158-805e-788e6591955e</id>
    <updated>2019-06-29T00:00:00Z</updated>
    <link href="http://www.amin.space/blog/latex_primer/" />
    <author>
      <name>Amin Mesbah</name>
    </author>
    <content type="html">&lt;p&gt;&lt;em&gt;Slides in PDF format are available &lt;a href=&quot;https://git.amin.space/latex-workshop/plain/presentation/presentation.pdf&quot; title=&quot;My introductory slides about LaTeX&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Back when I was a student, I found myself gazing into the abyss of Microsoft
Word with alarming frequency. A multi-hour session with that program could erode
anyone's mental stability. So, in an effort to retain my sanity, I learned
the &lt;a href=&quot;https://www.latex-project.org/&quot; title=&quot;Official website of the LaTeX Project&quot;&gt;LaTeX&lt;/a&gt; typesetting language.&lt;/p&gt;
&lt;p&gt;Those of you who use LaTeX may be laughing at that last sentence. Indeed, LaTeX
can be fairly described as abstruse, arcane, and archaic. Yet it's also the tool
I now reach for whenever I need to write printed work. It has advantages that
I haven't found anywhere else.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It's plain text.&lt;ul&gt;
&lt;li&gt;Use whatever text editor you want.&lt;/li&gt;
&lt;li&gt;Organize your work with your &lt;a href=&quot;https://fossil-scm.org/home/doc/trunk/www/index.wiki&quot; title=&quot;Fossil SCM&quot;&gt;favorite&lt;/a&gt; system for &lt;a href=&quot;https://en.wikipedia.org/wiki/Version_control&quot; title=&quot;Wikipedia article on Version Control&quot;&gt;version control&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Store your work in a file format that won't have decayed into
inaccessibility 100 years from now.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;It's programmable.&lt;ul&gt;
&lt;li&gt;Write your own functions that do stuff to the text.&lt;/li&gt;
&lt;li&gt;Use modules and templates written by other people.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;It's ancient and stable.&lt;ul&gt;
&lt;li&gt;In the 5 years I've been using LaTeX, I have never seen anything change.&lt;/li&gt;
&lt;li&gt;I have read 10 year old documentation that's not out of date.&lt;/li&gt;
&lt;li&gt;I have never had any issues with version incompatibility.&lt;/li&gt;
&lt;li&gt;There are many tools and resources for working with LaTeX.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In 2016 I prepared materials for an introductory workshop on LaTeX. That
workshop ended up never happening, but the slides and examples might still be
useful to someone getting started with LaTeX.&lt;/p&gt;
&lt;p&gt;You can find the slides &lt;a href=&quot;https://git.amin.space/latex-workshop/plain/presentation/presentation.pdf&quot; title=&quot;My introductory slides about LaTeX&quot;&gt;here&lt;/a&gt;. If you want, you can download the whole
&lt;a href=&quot;https://github.com/mesbahamin/latex-workshop&quot; title=&quot;My LaTeX Workshop Repository on GitHub&quot;&gt;repository&lt;/a&gt;, which includes some example documents. Those examples are also
online in an editable form:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.overleaf.com/read/mscbvnzkgvrh&quot;&gt;The Slides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.overleaf.com/read/hkqpqrjbqkrh&quot;&gt;Basic Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.overleaf.com/read/dvdsgcrvyrpw&quot;&gt;Lab Report Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.overleaf.com/read/jzkgmmnrwdnv&quot;&gt;Math Notes Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.overleaf.com/read/hczgnmdxfbkn&quot;&gt;MLA Essay Example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Until something better comes along, LaTeX is what I will continue to use for any
amount of serious printed writing.&lt;/p&gt;
</content>
  </entry>
  <entry xml:base="http://www.amin.space/blog/elemental_speller/">
    <title type="text">Spelling with Elemental Symbols</title>
    <id>urn:uuid:961a9d78-fffb-325b-9a60-5febedc725d1</id>
    <updated>2017-05-16T00:00:00Z</updated>
    <link href="http://www.amin.space/blog/elemental_speller/" />
    <author>
      <name>Amin Mesbah</name>
    </author>
    <content type="html">&lt;p&gt;&lt;em&gt;(Full source code is available &lt;a href=&quot;https://github.com/mesbahamin/stoichiograph&quot; title=&quot;Github page for my elemental spelling program, Stoichiograph&quot;&gt;here&lt;/a&gt;.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Sitting in my 5-hour-long chemistry class, my gaze would often drift over to the
periodic table posted on the wall. To pass the time, I began to try finding
words I could spell using only the symbols of the elements on the periodic
table. Some examples: ScAlEs, FeArS, ErAsURe, WAsTe, PoInTlEsSnEsS, MoISTeN,
SAlMoN, PuFFInEsS.&lt;/p&gt;
&lt;p&gt;I wondered what the longest such word was ('&lt;a href=&quot;https://www.poets.org/poetsorg/poem/bells&quot; title=&quot;The Bells by Edgar Allan Poe&quot;&gt;TiNTiNNaBULaTiONS&lt;/a&gt;' was the
longest one I could come up with). Then I started thinking about how nice it
would be to have a tool that could find the elemental spellings of &lt;em&gt;any&lt;/em&gt; word.
I decided to write a Python program. Given a word as input, it would output
&lt;em&gt;all&lt;/em&gt; elemental spellings for that word:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Input:&lt;ul&gt;
&lt;li&gt;'Amputations'&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Output:&lt;ul&gt;
&lt;li&gt;'AmPuTaTiONS', 'AmPUTaTiONS'&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Generating Character Groupings&lt;/h3&gt;
&lt;p&gt;If all the symbols of all the elements were the same length, the task would be
trivial. However some elemental symbols are glyphs consisting of two characters
('He'), while others are single-character glyphs ('O'). This turns out to make
things much more complex. The 'pu' in 'Amputations' can be represented either by
Plutonium ('Pu') or by Phosphorus and Uranium ('PU'). Any given word would need
to be broken down into all possible combinations of single and double-character
glyphs.&lt;/p&gt;
&lt;p&gt;I decided to call each of these permutations a 'grouping'. Groupings specify the
division of a word into glyphs. A grouping can be represented as a tuple of 1s
and 2s where 1 represents a single character glyph and 2 represents a double
character glyph. Every elemental spelling corresponds to some grouping:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;'AmPuTaTiONS'&lt;ul&gt;
&lt;li&gt;&lt;code&gt;(2,2,2,2,1,1,1)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;'AmPUTaTiONS'&lt;ul&gt;
&lt;li&gt;&lt;code&gt;(2,1,1,2,2,1,1,1)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In an attempt to explore the problem and find patterns, I wrote the following
table in my notebook:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Question&lt;/strong&gt;: For a string of length n, how many sequences of 1s and 2s exist
such that the sum equals n?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;
&lt;th&gt;n&lt;/th&gt;
&lt;th&gt;# Groupings&lt;/th&gt;
&lt;th&gt;Groupings&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(1)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(1,1)&lt;/code&gt;, &lt;code&gt;(2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(1,1,1)&lt;/code&gt;, &lt;code&gt;(2,1)&lt;/code&gt;, &lt;code&gt;(1,2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(1,1,1,1)&lt;/code&gt;, &lt;code&gt;(2,1,1)&lt;/code&gt;, &lt;code&gt;(1,2,1)&lt;/code&gt;, &lt;code&gt;(1,1,2)&lt;/code&gt;, &lt;code&gt;(2,2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(1,1,1,1,1)&lt;/code&gt;, &lt;code&gt;(2,1,1,1)&lt;/code&gt;, &lt;code&gt;(1,2,1,1)&lt;/code&gt;, &lt;code&gt;(1,1,2,1)&lt;/code&gt;, &lt;code&gt;(1,1,1,2)&lt;/code&gt;, &lt;code&gt;(2,2,1)&lt;/code&gt;, &lt;code&gt;(2,1,2)&lt;/code&gt;, &lt;code&gt;(1,2,2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(1,1,1,1,1,1)&lt;/code&gt;, &lt;code&gt;(2,1,1,1,1)&lt;/code&gt;, &lt;code&gt;(1,2,1,1,1)&lt;/code&gt;, &lt;code&gt;(1,1,2,1,1)&lt;/code&gt;, &lt;code&gt;(1,1,1,2,1)&lt;/code&gt;, &lt;code&gt;(1,1,1,1,2)&lt;/code&gt;, &lt;code&gt;(2,2,1,1)&lt;/code&gt;, &lt;code&gt;(2,1,2,1)&lt;/code&gt;, &lt;code&gt;(2,1,1,2)&lt;/code&gt;, &lt;code&gt;(1,2,2,1)&lt;/code&gt;, &lt;code&gt;(1,2,1,2)&lt;/code&gt;, &lt;code&gt;(1,1,2,2)&lt;/code&gt;, &lt;code&gt;(2,2,2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;&lt;code&gt;(1,1,1,1,1,1,1)&lt;/code&gt;, &lt;code&gt;(2,1,1,1,1,1)&lt;/code&gt;, &lt;code&gt;(1,2,1,1,1,1)&lt;/code&gt;, &lt;code&gt;(1,1,2,1,1,1)&lt;/code&gt;, &lt;code&gt;(1,1,1,2,1,1)&lt;/code&gt;, &lt;code&gt;(1,1,1,1,2,1)&lt;/code&gt;, &lt;code&gt;(1,1,1,1,1,2)&lt;/code&gt;, &lt;code&gt;(2,2,1,1,1)&lt;/code&gt;, &lt;code&gt;(2,1,2,1,1)&lt;/code&gt;, &lt;code&gt;(2,1,1,2,1)&lt;/code&gt;, &lt;code&gt;(2,1,1,1,2)&lt;/code&gt;, &lt;code&gt;(1,2,2,1,1)&lt;/code&gt;, &lt;code&gt;(1,2,1,2,1)&lt;/code&gt;, &lt;code&gt;(1,2,1,1,2)&lt;/code&gt;, &lt;code&gt;(1,1,2,2,1)&lt;/code&gt;, &lt;code&gt;(1,1,2,1,2)&lt;/code&gt;, &lt;code&gt;(1,1,1,2,2)&lt;/code&gt;, &lt;code&gt;(2,2,2,1)&lt;/code&gt;, &lt;code&gt;(2,2,1,2)&lt;/code&gt;, &lt;code&gt;(2,1,2,2)&lt;/code&gt;, &lt;code&gt;(1,2,2,2)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Answer&lt;/strong&gt;: &lt;code&gt;fib(n + 1)&lt;/code&gt;!?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I was surprised to find the Fibonacci sequence in this unexpected place. During
my subsequent investigations, I was even more surprised to &lt;a href=&quot;http://people.sju.edu/~rhall/mathforpoets.pdf&quot; title=&quot;Subhash Kak, 2000, Yamātārājabhānasalagāṃ an interesting combinatoric sūtra&quot;&gt;discover&lt;/a&gt; that
knowledge of this particular pattern goes back almost 2000 years to the
prosodists of ancient India, who discovered it in their study of the
permutations of short and long syllables of Vedic chants. For a fascinating
exploration of this and other advancements in the history of combinatorics,
consult section 7.2.1.7 of &lt;a href=&quot;https://books.google.com/books?id=56LNfE2QGtYC&amp;amp;pg=PA50&amp;amp;dq=Pingala#v=onepage&amp;amp;q&amp;amp;f=false&quot; title=&quot;The Art of Computer Programming, 7.2.1.7, page 50 on Google Books&quot;&gt;&lt;em&gt;The Art of Computer Programming&lt;/em&gt;&lt;/a&gt; by Donald
Knuth.&lt;/p&gt;
&lt;p&gt;Fascinating as this finding was, I still hadn't accomplished my actual goal: To
generate the groupings themselves. Some pondering and experimentation led me to
the most straightforward solution I could think of: to generate all possible
sequences of 1s and 2s, then filter out any that don't sum to the length of the
input word.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;itertools&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;generate_groupings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word_length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;glyph_sizes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cartesian_products&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;glyph_sizes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word_length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# include only groupings that represent the correct number of chars&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;groupings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;grouping&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grouping&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_iterable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cartesian_products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grouping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word_length&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;groupings&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Cartesian_product&quot; title=&quot;Wikipedia article on the Cartesian Product&quot;&gt;Cartesian product&lt;/a&gt; is the set of all tuples composed of a given set of
elements. The Python Standard Library provides &lt;a href=&quot;https://docs.python.org/3/library/itertools.html#itertools.product&quot; title=&quot;Python documentation for itertools.product()&quot;&gt;&lt;code&gt;itertools.product()&lt;/code&gt;&lt;/a&gt;,
a function that returns the Cartesian product of the elements in a given
iterable. &lt;code&gt;cartesian_products&lt;/code&gt; is a generator expression that yields every
possible permutation of the items in &lt;code&gt;glyph_sizes&lt;/code&gt; up to the given length,
&lt;code&gt;word_length&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So, if &lt;code&gt;word_length&lt;/code&gt; is 3, &lt;code&gt;cartesian_products&lt;/code&gt; will yield:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;[&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    (1,), (2,), (1, 1), (1, 2), (2, 1), (2, 2), (1, 1, 1), (1, 1, 2),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    (1, 2, 1), (1, 2, 2), (2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;These are then filtered so that &lt;code&gt;groupings&lt;/code&gt; ends up only including those
permutations whose elements add up to &lt;code&gt;word_length&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;generate_groupings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;((1, 2), (2, 1), (1, 1, 1))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Clearly, there is a lot of extra work being done here. The function calculated
14 permutations, but only ended up using 3. The performance gets rapidly worse
as &lt;code&gt;word_length&lt;/code&gt; increases. More on that later. Having gotten this function
working, I moved on to the next task.&lt;/p&gt;
&lt;h3&gt;Mapping Words to Groupings&lt;/h3&gt;
&lt;p&gt;Once all the possible groupings for a word have been calculated, that word can
be &quot;mapped&quot; to each grouping:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;map_word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grouping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;chars&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;mapped&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;glyph_size&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grouping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;glyph&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;glyph_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;glyph&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;mapped&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;glyph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mapped&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The function treats each glyph in the grouping like a cup, and fills it with as
many characters from the word as it can hold before moving on to the next one.
When all the characters have been placed in the proper glyph, resulting mapped
word is returned as a tuple.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map_word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;because&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;b&amp;#39;, &amp;#39;ec&amp;#39;, &amp;#39;a&amp;#39;, &amp;#39;u&amp;#39;, &amp;#39;se&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once a word is mapped, it's ready to be compared to the list of elemental
symbols to find any possible spellings.&lt;/p&gt;
&lt;h3&gt;Finding the Spellings&lt;/h3&gt;
&lt;p&gt;With the other two functions doing most of the work, I made a &lt;code&gt;spell()&lt;/code&gt; function
which tied everything together:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;spell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbols&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ELEMENTS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;groupings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;generate_groupings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;spellings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map_word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grouping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grouping&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;groupings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;elemental_spellings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spelling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spelling&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spellings&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spelling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;elemental_spellings&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;spell()&lt;/code&gt; gets all possible spellings, returning only those that are entirely
composed of elemental symbols. I used sets to efficiently filter out any invalid
spellings.&lt;/p&gt;
&lt;p&gt;Python's sets are are very similar to mathematical sets. They are unordered
collections of unique elements. Behind the scenes, they are implemented as
dictionaries (hash-tables) with keys, but no values. Since all the elements in
a set are hashable, membership tests are very efficient (&lt;a href=&quot;https://wiki.python.org/moin/TimeComplexity#set&quot; title=&quot;Table of big-O time complexity for various operations on Python sets&quot;&gt;average case &lt;code&gt;O(1)&lt;/code&gt;
time&lt;/a&gt;). The comparison operators are overloaded to test for &lt;a href=&quot;https://en.wikipedia.org/wiki/Subset&quot; title=&quot;Wikipedia article on subsets&quot;&gt;subsets&lt;/a&gt; by
using these efficient membership operations. Sets and dictionaries are deeply
explored in the wonderfully informative book, &lt;a href=&quot;http://shop.oreilly.com/product/0636920032519.do&quot; title=&quot;Fluent Python by Luciano Ramalho&quot;&gt;&lt;em&gt;Fluent Python&lt;/em&gt;&lt;/a&gt; by Luciano
Ramalho.&lt;/p&gt;
&lt;p&gt;With this last component functional, I finally had a working program!&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;amputation&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(&amp;#39;Am&amp;#39;, &amp;#39;Pu&amp;#39;, &amp;#39;Ta&amp;#39;, &amp;#39;Ti&amp;#39;, &amp;#39;O&amp;#39;, &amp;#39;N&amp;#39;), (&amp;#39;Am&amp;#39;, &amp;#39;P&amp;#39;, &amp;#39;U&amp;#39;, &amp;#39;Ta&amp;#39;, &amp;#39;Ti&amp;#39;, &amp;#39;O&amp;#39;, &amp;#39;N&amp;#39;)]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;cryptographer&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(&amp;#39;Cr&amp;#39;, &amp;#39;Y&amp;#39;, &amp;#39;Pt&amp;#39;, &amp;#39;Og&amp;#39;, &amp;#39;Ra&amp;#39;, &amp;#39;P&amp;#39;, &amp;#39;H&amp;#39;, &amp;#39;Er&amp;#39;)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;The Longest Word?&lt;/h3&gt;
&lt;p&gt;Happy to have implemented the core functionality, I gave my program a name
(&lt;a href=&quot;https://github.com/mesbahamin/stoichiograph&quot; title=&quot;Github page for my elemental spelling program, Stoichiograph&quot;&gt;Stoichiograph&lt;/a&gt;), and made a command line wrapper for it. The wrapper takes
words, either as arguments or from a file, and prints out their spellings. After
adding an option to order the words descendingly by length, I let my program
loose on my unsuspecting list of words.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ ./stoichiograph.py --sort --batch-file /usr/share/dict/american-english
NoNRePReSeNTaTiONaL
NoNRePReSeNTaTiONAl
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;...&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nice! That definitely wasn't a word I would have ever thought of myself. My
program was already fulfilling its purpose. I played around a bit and found
a longer word:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ ./stoichiograph.py nonrepresentationalisms
NoNRePReSeNTaTiONaLiSmS
NONRePReSeNTaTiONaLiSmS
NoNRePReSeNTaTiONAlISmS
NONRePReSeNTaTiONAlISmS
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Interesting. I wondered whether this was truly the longest word
(&lt;a href=&quot;/blog/elemental_speller/spoiler.txt&quot;&gt;spoiler&lt;/a&gt;), and I wanted to investigate &lt;a href=&quot;https://en.wikipedia.org/wiki/Longest_word_in_English&quot; title=&quot;Wikipedia article on the longest words in English&quot;&gt;longer words&lt;/a&gt;. First,
though, I needed to make my program run much faster.&lt;/p&gt;
&lt;h3&gt;Addressing Performance Issues&lt;/h3&gt;
&lt;p&gt;It took my program about 16 minutes to work through the 119,095 words (of which
many were quite short) in my word list:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt; ./stoichiograph.py --sort --batch-file /usr/share/dict/american-english
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;...&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
real    16m0.458s
user    15m33.680s
sys     0m23.173s
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That's about 120 words per second on average. I was sure I could make it faster.
I needed more detailed performance information to know how best to do so.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/rkern/line_profiler&quot; title=&quot;line_profiler: Line-by-line profiling for Python&quot;&gt;Line profiler&lt;/a&gt; is a tool for identifying performance bottlenecks in Python
code. I used it to profile my program as it found spellings for
a single 23-character-long word. Here's a condensed version of what it had to
say:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Line #   % Time   Line Contents
===============================
    30            @profile
    31            def spell(word, symbols=ELEMENTS):
    32     71.0       groupings = generate_groupings(len(word))
    33
    34     15.2       spellings = [map_word(word, grouping) for grouping in groupings]
    35
    36                elemental_spellings = [
    37      0.0           tuple(token.capitalize() for token in spelling)
    38     13.8           for spelling in spellings
    39                    if set(s.lower() for s in spelling) &amp;lt;= set(s.lower() for s in symbols)
    40                ]
    41
    42      0.0       return elemental_spellings

Line #   % Time   Line Contents
===============================
    45            @profile
    46            def generate_groupings(word_length, glyhp_sizes=(1, 2)):
    47                cartesian_products = (
    48      0.0           product(glyph_sizes, repeat=r)
    49      0.0           for r in range(1, word_length + 1)
    50                )
    51
    52      0.0       groupings = tuple(
    53      0.0           grouping
    54    100.0           for grouping in chain.from_iterable(cartesian_products)
    55                    if sum(grouping) == word_length
    56                )
    57
    58      0.0       return groupings
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It is not a great surprise that &lt;code&gt;generate_groupings()&lt;/code&gt; takes so long. The
problem it tries to solve is a special case of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Subset_sum_problem&quot; title=&quot;Wikipedia article on the subset sum problem&quot;&gt;subset sum problem&lt;/a&gt;
which is &lt;a href=&quot;https://en.wikipedia.org/wiki/NP-completeness&quot; title=&quot;Wikipedia article on NP-completeness&quot;&gt;NP-complete&lt;/a&gt;. Finding a cartesian product gets expensive quickly,
and &lt;code&gt;generate_groupings()&lt;/code&gt; finds multiple cartesian products.&lt;/p&gt;
&lt;p&gt;We can perform asymptotic analysis to get a sense of just how horrifically bad
things are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We assume that &lt;code&gt;glyph_sizes&lt;/code&gt; always has 2 elements (1 and 2).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;product()&lt;/code&gt; finds the cartesian product of a set of 2 elements &lt;code&gt;r&lt;/code&gt; times, so
the big O of &lt;code&gt;product()&lt;/code&gt; is &lt;code&gt;O(2^r)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;product()&lt;/code&gt; is called in a for loop which repeats &lt;code&gt;word_length&lt;/code&gt; times, so if
we set &lt;code&gt;n&lt;/code&gt; as &lt;code&gt;word_length&lt;/code&gt;, the big O for the whole loop is &lt;code&gt;O(2^r * n)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;But &lt;code&gt;r&lt;/code&gt; has a different value each time the loop runs, so really it's more
like &lt;code&gt;O(2^1 + 2^2 + 2^3 + ... + 2^(n-1) + 2^n)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;And since &lt;code&gt;2^0 + 2^1 + ... + 2^n = 2^(n+1) - 1&lt;/code&gt;, our final big O is:
&lt;code&gt;O(2^(n+1) - 1)&lt;/code&gt;, or &lt;code&gt;O(2^n)&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With &lt;code&gt;O(2^n)&lt;/code&gt; time complexity we can expect the execution time to double for
each incrementation of &lt;code&gt;word_length&lt;/code&gt;. Horrifying!&lt;/p&gt;
&lt;p&gt;I thought about this performance problem for many weeks. I had two related, but
distinct, performance cases to consider:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Processing a list of words of varying length.&lt;/li&gt;
&lt;li&gt;Processing a single, but very long word.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The second case proved, as one might guess, to be much more important because it
affected the first. Though I didn't immediately know how to improve case 2,
I had some ideas for case 1, so that's where I started.&lt;/p&gt;
&lt;h4&gt;Case 1: Being Lazy&lt;/h4&gt;
&lt;p&gt;Laziness is a virtue not only for &lt;a href=&quot;http://wiki.c2.com/?LazinessImpatienceHubris&quot; title=&quot;The three great virtues of a programmer&quot;&gt;programmers&lt;/a&gt;, but also for programs
themselves. Addressing case 1 required laziness. If my program was going to
process a long list of words, how could I get my program to do as little work as
possible?&lt;/p&gt;
&lt;h5&gt;Checking for Invalid Characters&lt;/h5&gt;
&lt;p&gt;Surely, I thought, there are likely to be words in a given list that contain
characters not present in any elemental symbol. Time expended trying to find
spellings for these words is time wasted. A word list could be processed faster
if these words were quickly identified and skipped.&lt;/p&gt;
&lt;p&gt;Unfortunately for me, it turns out that 'j' and 'q' are the only letters not
contained in any elemental symbol:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;abcdefghijklmnopqrstuvwxyz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ELEMENTS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;j&amp;#39;, &amp;#39;q&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And only about 3% of the words in my particular dictionary file contain 'j' or
'q':&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/usr/share/dict/american-english&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readlines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;words&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;invalid_char_words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;words&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;j&amp;#39;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;q&amp;#39;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;invalid_char_words&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3.3762962340988287&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Skipping those words made the program only about 2% faster:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt; ./stoichiograph.py --sort --batch-file /usr/share/dict/american-english
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;...&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
real    15m44.246s
user    15m17.557s
sys     0m22.980s
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Not the kind of performance improvement I was hoping for, so on to the next
idea.&lt;/p&gt;
&lt;h5&gt;Memoization&lt;/h5&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Memoization&quot; title=&quot;Wikipedia article on memoization&quot;&gt;Memoization&lt;/a&gt; is the technique of saving a function's output and returning
it if the function is called again with the same inputs. A memoized function
only needs to generate output once for a given input. This can be very helpful
with expensive functions that are called many times with the same few inputs,
but only works for pure functions.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;generate_groupings()&lt;/code&gt; was the perfect candidate. It was unlikely to encounter
a very large range of inputs, and was very expensive for long word lengths. The
&lt;code&gt;functools&lt;/code&gt; package makes memoization trivial by supplying the
&lt;a href=&quot;https://docs.python.org/3/library/functools.html#functools.lru_cache&quot; title=&quot;Python documentation for functools.lru_cache&quot;&gt;&lt;code&gt;@lru_cache()&lt;/code&gt;&lt;/a&gt; decorator.&lt;/p&gt;
&lt;p&gt;Memoizing &lt;code&gt;generate_groupings()&lt;/code&gt; lead to a notable, though still not
satisfactory reduction in execution time:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt; ./stoichiograph.py --sort --batch-file /usr/share/dict/american-english
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;...&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
real    11m15.483s
user    10m54.553s
sys     0m17.083s
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Still, that's not bad for a single decorator from the standard library!&lt;/p&gt;
&lt;h4&gt;Case 2: Being Clever&lt;/h4&gt;
&lt;p&gt;My optimizations so far had helped slightly with case 1, but the core problem,
the inefficiency of &lt;code&gt;generate_groupings()&lt;/code&gt; hadn't been addressed, and big
individual words still took too long to process:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt; ./stoichiograph.py nonrepresentationalisms
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;...&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
real    0m20.275s
user    0m20.220s
sys     0m0.037s
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Laziness can yield a certain degree of success, but sometimes cleverness is
needed.&lt;/p&gt;
&lt;h5&gt;Recursion and the DAG&lt;/h5&gt;
&lt;p&gt;One evening as I was dosing off, I had a flash of inspiration and ran to my
whiteboard to draw this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog/elemental_speller/recursive_algorithm_whiteboard.png&quot; alt=&quot;Photograph of whiteboard diagram of recursive algorithm&quot;&gt;&lt;/p&gt;
&lt;p&gt;I realized I can take any string, pop the 1 and 2-character glyphs off the
front, then &lt;a href=&quot;https://en.wikipedia.org/wiki/Recursion_(computer_science)&quot; title=&quot;Wikipedia article on recursion&quot;&gt;recurse&lt;/a&gt; into the remaining substring in both cases. Once I've
traversed the whole string, I will have found all the glyphs, and, &lt;em&gt;critically&lt;/em&gt;,
I will have information about their structure and order. I also realized that
a graph could be a very good way to store this information.&lt;/p&gt;
&lt;p&gt;So if the series of recursive function calls into our charming example word,
'amputation', looks something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;'a' 'mputation'
    'm' 'putation'
        'p' 'utation'
            'u' 'tation'
                't' 'ation'
                    'a' 'tion'
                        't' 'ion'
                            'i' 'on'
                                'o' 'n'
                                    'n' ''
                                'on' ''
                            'io' 'n'
                        'ti' 'on'
                    'at' 'ion'
                'ta' 'tion'
            'ut' 'ation'
        'pu' 'tation'
    'mp' 'utation'
'am' 'putation'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, after filtering out all the glyphs that don't match any elemental symbol,
we could end up with a nice graph like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog/elemental_speller/directed_acyclic_graph.svg&quot; alt=&quot;Diagram of directed acyclic graph representing the spellings of &amp;#39;Amputation&amp;#39;&quot; title=&quot;Example of a directed acyclic graph&quot;&gt;&lt;/p&gt;
&lt;p&gt;Specifically, we will have made a &lt;a href=&quot;https://en.wikipedia.org/wiki/Directed_acyclic_graph&quot; title=&quot;Wikipedia article on directed acyclic graphs&quot;&gt;directed acyclic graph&lt;/a&gt; (DAG) with each
node holding a glyph. Each path from the first node to the last would be a valid
elemental spelling of the original word!&lt;/p&gt;
&lt;p&gt;I had never worked with graphs before, but I found a very helpful &lt;a href=&quot;https://www.python.org/doc/essays/graphs/&quot; title=&quot;Python.org article on implementing graphs&quot;&gt;essay&lt;/a&gt; on
the Python website that explained the basics, including how to efficiently find
all paths between two nodes. The wonderful book &lt;a href=&quot;http://aosabook.org/en/index.html&quot; title=&quot;A collection of free online books including &amp;#39;500 Lines or Less&amp;#39;&quot;&gt;&lt;em&gt;500 Lines or Less&lt;/em&gt;&lt;/a&gt; has
a &lt;a href=&quot;http://www.aosabook.org/en/500L/contingent-a-fully-dynamic-build-system.html&quot; title=&quot;Chapter 4 from &amp;#39;500 Lines or Less&amp;#39;&quot;&gt;chapter&lt;/a&gt; with another example of a graph implementation in Python.
I based my graph class on these examples.&lt;/p&gt;
&lt;p&gt;With a simple graph class implemented and tested, I turned my whiteboard drawing
into a function:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# A single node of the graph. A glyph and its position in the word.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;namedtuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Node&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;position&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;build_spelling_graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbols&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ELEMENTS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Given a word and a graph, find all single and double-character&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    glyphs in the word. Add them to the graph only if they are present&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    within the given set of allowed symbols.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;pop_root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remaining&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;previous_root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remaining&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_edge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;previous_root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;single_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remaining&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;single_root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_edge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;previous_root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;single_root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remaining&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;processed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;pop_root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;remaining&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;previous_root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;single_root&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remaining&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;double_root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remaining&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;double_root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;symbols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;graph&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_edge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;previous_root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;double_root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remaining&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;processed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;pop_root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;remaining&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;position&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;previous_root&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;double_root&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;processed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remaining&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;processed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pop_root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;word&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;The Payoff&lt;/h4&gt;
&lt;p&gt;Where the initial brute-force algorithm operated horrifyingly in &lt;code&gt;O(2^n)&lt;/code&gt; time,
this recursive one operates in &lt;code&gt;O(n)&lt;/code&gt; time. Much better! The first time I timed my
newly optimized program on my word list file, I was blown away:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt; ./stoichiograph.py --sort --batch-file /usr/share/dict/american-english
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;...&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
real    0m11.299s
user    0m11.020s
sys     0m0.17ys
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Execution time had gone from 16 minutes down to 10 seconds, the processing rate
from 120 words per second to 10,800!&lt;/p&gt;
&lt;p&gt;This was the first time I truly appreciated the power and value of data
structures and algorithms.&lt;/p&gt;
&lt;h3&gt;The Actual Longest Word&lt;/h3&gt;
&lt;p&gt;With this newfound power I was able to find a new longest elementally spellable
word: 'floccinaucinihilipilificatiousness.'&lt;/p&gt;
&lt;p&gt;This amazing word comes from '&lt;a href=&quot;https://en.wiktionary.org/wiki/floccinaucinihilipilification&quot; title=&quot;Wiktionary article on the word floccinaucinihilipilification&quot;&gt;floccinaucinihilipilification&lt;/a&gt;,' defined
as &quot;the act or habit of describing or regarding something as unimportant, of
having no value or being worthless,&quot; and often cited as the longest
non-technical English word. 'Floccinaucinihilipilificatiousness' has 54
elemental spellings, all of which can experienced by any explorer brave enough
to traverse its beautiful graph:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/blog/elemental_speller/longest_word.svg&quot;&gt;&lt;img src=&quot;/blog/elemental_speller/longest_word.svg&quot; alt=&quot;Diagram of directed acyclic graph representing the spellings of &amp;#39;floccinaucinihilipilificatiousness&amp;#39;&quot; title=&quot;If you get lost, just go with the flow.&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Time Well Spent&lt;/h3&gt;
&lt;p&gt;One may be tempted to floccinaucinihilipilificate on this whole endeavor, but
I found it both valuable and important. When I began this project, I was
relatively inexperienced at programming, and had no idea how to even begin.
Progress was slow, and it took a long time to arrive at a satisfactory solution
(look at the &lt;a href=&quot;https://github.com/mesbahamin/stoichiograph/commits/master&quot; title=&quot;Commit history for Stoichiograph&quot;&gt;commit history&lt;/a&gt; to see the large gaps where I took a break to
work on other projects).&lt;/p&gt;
&lt;p&gt;However, I learned a great deal along the way. This project introduced me to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Combinatorics&lt;/li&gt;
&lt;li&gt;Performance profiling&lt;/li&gt;
&lt;li&gt;Time complexity&lt;/li&gt;
&lt;li&gt;Memoization&lt;/li&gt;
&lt;li&gt;Recursion&lt;/li&gt;
&lt;li&gt;Graphs and trees&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Understanding these concepts has helped me again and again. Recursion and trees
have been particularly important for my &lt;a href=&quot;https://www.amin.space/blog/2017/5/quadtree_debug/&quot; title=&quot;Post about debugging a quadtree for a physics simulation&quot;&gt;n-body simulation project&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, it feels good to have answered my own initial question. I no longer
have to wonder about elemental spellings because I now have a tool to find them
for me, and with a quick &lt;code&gt;pip install stoichiograph&lt;/code&gt;, you can too.&lt;/p&gt;
&lt;h5&gt;Discussion&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Some nice people (and a few well-intentioned bots) have participated in
a &lt;a href=&quot;https://www.reddit.com/r/programming/comments/6bgxia/using_python_to_find_the_longest_word_spellable/?ref=share&amp;amp;ref_source=link&quot; title=&quot;Discussion of this article on r/programming.&quot;&gt;discussion&lt;/a&gt; of this article on r/programming.&lt;/li&gt;
&lt;li&gt;This article was featured on &lt;a href=&quot;https://pythonbytes.fm/episodes/show/26/how-have-you-automated-your-life-or-cli-with-python&quot; title=&quot;Episode #26 of the Python Bytes podcast&quot;&gt;Episode #26&lt;/a&gt; of the excellent weekly
podcast, &lt;a href=&quot;https://pythonbytes.fm/&quot; title=&quot;Python Bytes: &amp;#39;Python headlines delivered directly to your earbuds&amp;#39;&quot;&gt;&lt;em&gt;Python Bytes&lt;/em&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Further Reading&lt;/h5&gt;
&lt;p&gt;Matus Goljer wrote a follow-up article that explores the generation of character
groupings with dynamic programming:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://fuco1.github.io/2017-05-28-Generating-all-groupings-of-(1%7C2)*-summing-up-to-m.html&quot; title=&quot;Article on generating character groupings with dynamic programming.&quot;&gt;&lt;em&gt;Generating all groupings of (1|2)&amp;ast; summing up to m&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I drew much inspiration from Peter Norvig's elegant solutions to interesting problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://norvig.com/spell-correct.html&quot; title=&quot;Peter Norvig&amp;#39;s wonderfully elegant spell-checker&quot;&gt;&lt;em&gt;How to Write a Spelling Corrector&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://norvig.com/sudoku.html&quot; title=&quot;Peter Norvig&amp;#39;s wonderfully elegant sudoku solver&quot;&gt;&lt;em&gt;Solving Every Sudoku Puzzle&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Two informative articles about performance profiling in Python:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://blog.thehumangeo.com/2015/07/28/profiling-in-python/&quot; title=&quot;Profiling in Python&quot;&gt;&lt;em&gt;Profiling in Python&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20170205202156/https://www.huyng.com/posts/python-performance-analysis&quot; title=&quot;A Guide to Analyzing Python Performance&quot;&gt;&lt;em&gt;A Guide to Analyzing Python Performance&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  <entry xml:base="http://www.amin.space/blog/quadtree_debug/">
    <title type="text">Debugging a Quadtree in C</title>
    <id>urn:uuid:8b135d1a-0999-3457-b73b-a904bbfc340a</id>
    <updated>2017-05-12T00:00:00Z</updated>
    <link href="http://www.amin.space/blog/quadtree_debug/" />
    <author>
      <name>Amin Mesbah</name>
    </author>
    <content type="html">&lt;p&gt;I've been working on a &lt;a href=&quot;https://github.com/mesbahamin/star-garden&quot; title=&quot;Github repo for my particle simulation project&quot;&gt;project&lt;/a&gt; that simulates stars or particles and the
forces of attraction between them. To make the simulation more efficient and
able to handle more particles, I've been working on implementing a &lt;a href=&quot;https://en.wikipedia.org/wiki/Barnes%E2%80%93Hut_simulation&quot; title=&quot;Wikipedia article on Barnes-Hut simulations&quot;&gt;Barnes-Hut
Algorithm&lt;/a&gt; by using a quadtree to partition the simulation space. When it
works, it's beautiful:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog/quadtree_debug/barnes_hut.gif&quot; alt=&quot;Gif of the Barnes-Hut spatial partition at work&quot; title=&quot;The quadtree at work&quot;&gt;&lt;/p&gt;
&lt;p&gt;Today made a breakthrough on a bug in my quadtree implementation. I had been
getting very occasional segfaults, and Valgrind was complaining of invalid reads
and free()s. I haven't had much time to work on the problem for the past two
weeks, but I was often thinking about it (and even, with an unnerving frequency,
dreaming about it). When I had an hour here or there, I would return to my
investigation and continue my attempt to understand the cause of the problem.
Eventually I made the minimal working example below.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;//qt_test.c&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#define NUM_UPDATES 10&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define QUAD_TREE_LEVELS 3&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTreeNode&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTreeNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTreeNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTreeNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTreeNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;se&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTreeNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTreeNode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;quad_tree_node_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTreeNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTreeNode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTreeNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ne&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;se&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;quad_tree_node_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTreeNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;quad_tree_node_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;quad_tree_node_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;quad_tree_node_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;quad_tree_node_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;se&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;quad_tree_node_subdivide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTreeNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remaining_levels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remaining_levels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;remaining_levels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ne&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quad_tree_node_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quad_tree_node_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sw&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quad_tree_node_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;se&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quad_tree_node_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;quad_tree_node_subdivide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ne&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remaining_levels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;quad_tree_node_subdivide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remaining_levels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;quad_tree_node_subdivide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remaining_levels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;quad_tree_node_subdivide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;se&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;remaining_levels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;quad_tree_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quad_tree_node_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;quad_tree_node_subdivide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QUAD_TREE_LEVELS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;quad_tree_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;quad_tree_node_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;quad_tree_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quad_tree_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quad_tree_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NUM_UPDATES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Update %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;quad_tree_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here's a sample from the output of &lt;code&gt;valgrind --track-origins=yes ./qt_test&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Invalid read of size 8
==16345==    at 0x1088B7: quad_tree_node_free (qt_test.c:43)
==16345==    by 0x1089DB: quad_tree_free (qt_test.c:82)
==16345==    by 0x108A00: update (qt_test.c:90)
==16345==    by 0x108A5D: main (qt_test.c:102)
==16345==  Address 0x5e350a0 is 16 bytes inside a block of size 32 free'd
==16345==    at 0x4C2C14B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16345==    by 0x1088D0: quad_tree_node_free (qt_test.c:45)
==16345==    by 0x1089DB: quad_tree_free (qt_test.c:82)
==16345==    by 0x108A00: update (qt_test.c:90)
==16345==    by 0x108A5D: main (qt_test.c:102)
==16345==  Block was alloc'd at
==16345==    at 0x4C2AF1F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16345==    by 0x10885E: quad_tree_node_init (qt_test.c:25)
==16345==    by 0x1089A0: quad_tree_init (qt_test.c:71)
==16345==    by 0x108A30: main (qt_test.c:97)

[...]

==16345== Invalid free() / delete / delete[] / realloc()
==16345==    at 0x4C2C14B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16345==    by 0x1088D0: quad_tree_node_free (qt_test.c:45)
==16345==    by 0x1088AD: quad_tree_node_free (qt_test.c:41)
==16345==    by 0x1088BF: quad_tree_node_free (qt_test.c:43)
==16345==    by 0x1089DB: quad_tree_free (qt_test.c:82)
==16345==    by 0x108A00: update (qt_test.c:90)
==16345==    by 0x108A5D: main (qt_test.c:102)
==16345==  Address 0x5e35570 is 0 bytes inside a block of size 32 free'd
==16345==    at 0x4C2C14B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16345==    by 0x1088D0: quad_tree_node_free (qt_test.c:45)
==16345==    by 0x1088AD: quad_tree_node_free (qt_test.c:41)
==16345==    by 0x1088BF: quad_tree_node_free (qt_test.c:43)
==16345==    by 0x1089DB: quad_tree_free (qt_test.c:82)
==16345==    by 0x108A00: update (qt_test.c:90)
==16345==    by 0x108A5D: main (qt_test.c:102)
==16345==  Block was alloc'd at
==16345==    at 0x4C2AF1F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16345==    by 0x10885E: quad_tree_node_init (qt_test.c:25)
==16345==    by 0x10890B: quad_tree_node_subdivide (qt_test.c:54)
==16345==    by 0x108958: quad_tree_node_subdivide (qt_test.c:61)
==16345==    by 0x1089B0: quad_tree_init (qt_test.c:72)
==16345==    by 0x108A30: main (qt_test.c:97)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I was baffled for quite a while by these errors. I spent a lot of time checking
and re-checking all the functions that init and free the quadtree and quadtree
nodes. Only after expending great effort did I finally determine the cause.&lt;/p&gt;
&lt;p&gt;The problem turned out to lie with the way I was passing my struct around to
different functions. I'm used to C++, in which one can pass things either by
value or by reference, but in C, everything is passed by value. My &lt;code&gt;update()&lt;/code&gt;
function was changing its local copy of the &lt;code&gt;QuadTree *&lt;/code&gt;, &lt;code&gt;qt&lt;/code&gt;, but that change
did not apply to the original &lt;code&gt;qt&lt;/code&gt; in &lt;code&gt;main()&lt;/code&gt;. That meant that all the calls to
&lt;code&gt;qt&lt;/code&gt; in &lt;code&gt;main()&lt;/code&gt; were accessing the old memory that had been freed.&lt;/p&gt;
&lt;h3&gt;Another Level of Indirection&lt;/h3&gt;
&lt;p&gt;The first solution I found was to change &lt;code&gt;update()&lt;/code&gt; to take a &lt;code&gt;QuadTree **&lt;/code&gt;
parameter:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;quad_tree_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quad_tree_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then in &lt;code&gt;main()&lt;/code&gt; I called it like:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now that the &lt;code&gt;qt&lt;/code&gt; parameter was wrapped in an extra pointer, changes to it in
&lt;code&gt;update()&lt;/code&gt; were now being properly applied to &lt;code&gt;qt&lt;/code&gt; in &lt;code&gt;main()&lt;/code&gt;. Valgrind's
previous complaints were gone. It was a nice example to support the claim that
&quot;All problems in computer science can be solved by &lt;a href=&quot;https://en.wikipedia.org/wiki/Indirection&quot; title=&quot;Wikipedia article on indirection&quot;&gt;another level of
indirection&lt;/a&gt;.&quot;&lt;/p&gt;
&lt;h3&gt;Change Only What Needs Changing&lt;/h3&gt;
&lt;p&gt;I also found another way of solving the problem. I already had a &lt;code&gt;QuadTree&lt;/code&gt;
struct which conveniently wrapped the rest of the actual tree and kept track of
the root. I realized that there was no reason to continually be freeing and
reallocating &lt;code&gt;qt&lt;/code&gt; itself.&lt;/p&gt;
&lt;p&gt;I simplified the &lt;code&gt;QuadTree&lt;/code&gt; functions to basically be &quot;run-once&quot;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;quad_tree_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;malloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;sizeof&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;quad_tree_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;quad_tree_node_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I changed my update function to only operate on &lt;code&gt;qt-&amp;gt;root&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;quad_tree_node_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quad_tree_node_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;quad_tree_node_subdivide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QUAD_TREE_LEVELS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And I updated my main function accordingly:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QuadTree&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quad_tree_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quad_tree_node_init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;quad_tree_node_subdivide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;QUAD_TREE_LEVELS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NUM_UPDATES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Update %d&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;quad_tree_free&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;qt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Still no errors from Valgrind! &lt;code&gt;qt&lt;/code&gt; is happy to point to the same memory address
for most of the program.&lt;/p&gt;
&lt;p&gt;I'm not sure which of these solutions is more appropriate, but that will become
clear with time. I'm happy to have gained a deeper understanding of pointers,
the implications of pass-by-value in C, and some C idioms with which to deal
with similar situations.&lt;/p&gt;
&lt;!-- Links --&gt;

</content>
  </entry>
  <entry xml:base="http://www.amin.space/blog/default_copy_constructor/">
    <title type="text">Dangers of the Default Copy Constructor</title>
    <id>urn:uuid:ef41cbe4-8607-39c4-a19a-9f0c34fab934</id>
    <updated>2017-01-07T00:00:00Z</updated>
    <link href="http://www.amin.space/blog/default_copy_constructor/" />
    <author>
      <name>Amin Mesbah</name>
    </author>
    <content type="html">&lt;p&gt;Learning C++ is hard. Arrays, pointers, compilation, the stack and the heap, and
memory allocation all seem straightforward to those versed in their subtleties.
However, the beginner is confronted with a cluster of difficult concepts
demanding seemingly abstruse knowledge about the C++ spec. and the inner
workings of computers. These matters are complicated further when combined with
classes, objects, and the host of concepts associated with object-oriented
programming. The syntax, subtle and unforgiving, hardly makes the initial steps
of the journey any easier.&lt;/p&gt;
&lt;p&gt;Tutoring C++ has provided me with ample opportunity to clarify and explain such
concepts. I've become familiar with the pain points of the first two semesters
of C++, and I'm confident in my ability to help students work through them. Yet
I am still a beginner and constantly learning new things. Students occasionally
run into perplexing bugs that make quite evident the limits of my understanding.&lt;/p&gt;
&lt;p&gt;On one such occasion, I was helping a student debug her code for a string class.
Her professor had provided a header file, &lt;code&gt;MyString.h&lt;/code&gt;, and a test program,
&lt;code&gt;my_string_test.cpp&lt;/code&gt;. Both of these, the professor had warned, were &lt;em&gt;not&lt;/em&gt; to be
altered. The student's task was to implement the class in &lt;code&gt;MyString.cpp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For the sake of clarity (not to mention adherence to academic ethics), the code
here included is greatly simplified. Numerous methods and overloaded operators
are omitted.&lt;/p&gt;
&lt;h6&gt;&lt;code&gt;MyString.h&lt;/code&gt;&lt;/h6&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#ifndef MyString_H&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#define MyString_H&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;cstring&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyString&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;str_length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;friend&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;the_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// The number of characters in the string up to, but not&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// including, the null terminator &amp;#39;\0&amp;#39;.&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#endif&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h6&gt;&lt;code&gt;my_string_test.cpp&lt;/code&gt;&lt;/h6&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;quot;MyString.h&amp;quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// String literal constructor&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;A string literal.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;first: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// Copy constructor&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;second&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;second: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;second&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The class keeps track of a null-terminated array of characters. It has two
member variables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;the_string&lt;/code&gt; is a &lt;code&gt;char*&lt;/code&gt; to the memory where the null-terminated string is
stored.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;length&lt;/code&gt; is an &lt;code&gt;int&lt;/code&gt; that stores the number of characters not including the
null terminator.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When she came in for help, the student had already implemented and tested most
of the class. Her implementation looked something like this:&lt;/p&gt;
&lt;h6&gt;&lt;code&gt;MyString.cpp&lt;/code&gt;&lt;/h6&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;quot;MyString.h&amp;quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;cstring&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;the_string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;the_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&amp;#39;\0&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;the_string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;the_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;the_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&amp;#39;\0&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::~&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str_length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;operator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;strm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;the_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;The Problem&lt;/h3&gt;
&lt;p&gt;Until she had implemented the destructor, &lt;code&gt;MyString::~MyString()&lt;/code&gt;, everything
had apparently been working perfectly. Running the program, I was surprised to
see the following debug errors:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog/default_copy_constructor/msvc_access_violation.png&quot; alt=&quot;screenshot visual studio access violation window&quot; title=&quot;Access Violation&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog/default_copy_constructor/msvc_debug_assertion_failed.png&quot; alt=&quot;screenshot visual studio debug assertion failed window&quot; title=&quot;Debug Assertion Failed&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog/default_copy_constructor/msvc_heap_corruption_detected.png&quot; alt=&quot;screenshot visual studio heap corruption detected window&quot; title=&quot;Heap Corruption Detected&quot;&gt;&lt;/p&gt;
&lt;p&gt;Overlooking these somewhat enigmatic error messages, I commented out the
destructor's definition. The program executed without any issues:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog/default_copy_constructor/successful_run.png&quot; alt=&quot;screenshot of program successfully running in a terminal&quot; title=&quot;Running without destructor&quot;&gt;&lt;/p&gt;
&lt;p&gt;The destructor was simple, merely freeing the memory pointed to by &lt;code&gt;the_string&lt;/code&gt;.
I wondered how it could be causing these problems. I decided to step through the
program line by line in the Visual Studio debugger. We found that the debug
errors didn't appear until the execution of &lt;code&gt;return 0&lt;/code&gt; at the end of &lt;code&gt;main()&lt;/code&gt;.
Baffling.&lt;/p&gt;
&lt;p&gt;Visual Studio's disassembly view divulged the details of what the processor was
being told to do. There were 2 calls to &lt;code&gt;MyString::~MyString()&lt;/code&gt; (1 for each
&lt;code&gt;MyString&lt;/code&gt; object) after &lt;code&gt;return 0&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[...]&lt;/span&gt;
&lt;span class=&quot;mf&quot;&gt;0027645F&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;cmp&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;esi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;esp&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;00276461&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;call&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;__RTC_CheckEsp&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;0271352&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;mo&quot;&gt;00276466&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;mov&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;dword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0F&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;00276470&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;mov&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;00276474&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;lea&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;ecx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;second&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;00276477&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;call&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::~&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;02711&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CCh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;0027647&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;mov&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;dword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0FF&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FFFFFFh&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;002764&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;lea&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;ecx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;002764&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;86&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;call&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::~&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;02711&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CCh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;002764&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;mov&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;eax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0F&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[...]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first destructor call would execute as expected, but the second would raise
the error messages. A few carefully observed runs through the debugger revealed
the problem: The first &lt;code&gt;MyString&lt;/code&gt; object's destructor was freeing memory for
both objects' pointers. This was the state after that first call:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog/default_copy_constructor/dbg_calling_first_destructor.png&quot; alt=&quot;screenshot of msvc local and watch windows after calling the first destructor&quot; title=&quot;State after first destructor was called&quot;&gt;
&lt;em&gt;The first destructor frees memory for both objects! (&lt;a href=&quot;/blog/default_copy_constructor/dbg_calling_first_destructor_full.png&quot;&gt;full screenshot&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Note that &lt;code&gt;first.the_string&lt;/code&gt; and &lt;code&gt;second.the_string&lt;/code&gt; are both pointing to the
same memory address! The second destructor was trying to free the same memory as
the first. Memory can't be freed twice, so an exception was raised. Finally we
understood the cause of the error messages.&lt;/p&gt;
&lt;p&gt;When two pointers reference the same memory address, they are said to be
'&lt;a href=&quot;https://en.wikipedia.org/wiki/Pointer_aliasing&quot; title=&quot;Pointer Aliasing&quot;&gt;aliased&lt;/a&gt;'. Pointer aliasing is a harbinger of untold woe, and should
generally be avoided. I searched through the student's code, but I could find no
statement that could have aliased the two &lt;code&gt;the_string&lt;/code&gt; pointers. How could it be
happening if the student had written no code to make it happen? Many minutes
were spent carefully stepping through each line of the code before we found the
unexpected source of the problem: The professor's code.&lt;/p&gt;
&lt;p&gt;The professor had included a test of the &lt;code&gt;MyString&lt;/code&gt; class copy constructor in
&lt;code&gt;my_string_test.cpp&lt;/code&gt;, but no prototype for it in &lt;code&gt;MyString.h&lt;/code&gt;. The student,
having been forbidden to alter these files, had not defined the copy constructor
in &lt;code&gt;MyString.cpp&lt;/code&gt;. One would expect the compiler to loudly complain about such
a situation, but it appeared instead to be implicitly creating a constructor of
its own:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[...]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;second&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;mo&quot;&gt;00276415&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;push&lt;/span&gt;        &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;00276417&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;lea&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;ecx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;second&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;0027641&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;call&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__autoclassinit2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mo&quot;&gt;02713&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CFh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  
&lt;span class=&quot;mf&quot;&gt;0027641F&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;mov&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;eax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;00276422&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;mov&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;dword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;second&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eax&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;00276425&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;mov&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;ecx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;0027642&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;mov&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;dword&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ecx&lt;/span&gt;  
&lt;span class=&quot;mo&quot;&gt;0027642&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;B&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;mov&lt;/span&gt;         &lt;span class=&quot;n&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ebp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;[...]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This was the state after executing that second &lt;code&gt;mov&lt;/code&gt;. Note the aliased pointers:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog/default_copy_constructor/dbg_calling_default_copy_con.png&quot; alt=&quot;screenshot of msvc local and watch windows after calling default copy constructor&quot; title=&quot;State after default copy constructor was called&quot;&gt;
&lt;em&gt;The default copy constructor sets both pointers to the same memory address! (&lt;a href=&quot;/blog/default_copy_constructor/dbg_calling_default_copy_con_full.png&quot;&gt;full screenshot&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;After a bit of research, we learned that when no copy constructor is defined,
the compiler will automatically generate a &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/63kwz036(v=vs.120).aspx&quot; title=&quot;MSDN default copy constructor documentation&quot;&gt;default copy constructor&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;A compiler-generated copy constructor sets up a new object and performs
a memberwise copy of the contents of the object to be copied. If base class or
member constructors exist, they are called; otherwise, bitwise copying is
performed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This copy constructor performs naive memberwise assignment, copying the values
of each member variable of one object to the corresponding variable in the
other. This can be adequate for extremely basic classes, but proves to be
disastrous when classes have pointer member variables. The address of one
pointer is directly copied to another, and so it went with &lt;code&gt;the_string&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;The Solution&lt;/h3&gt;
&lt;p&gt;As is the case with many errors, once we understood its cause, it was trivial to
fix. The student created a proper copy constructor and, in an entirely
justifiable violation of the rules, added a prototype for it to &lt;code&gt;MyString.h&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;// MyString.cpp&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MyString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;the_string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;the_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;the_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;the_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&amp;#39;\0&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Stepping through the code a final time, we could see that, after this new copy
constructor was called, each &lt;code&gt;MyString&lt;/code&gt; object had its own memory:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog/default_copy_constructor/dbg_calling_custom_copy_con.png&quot; alt=&quot;screenshot of msvc local and watch windows after calling the custom copy constructor&quot; title=&quot;State after new copy constructor was called&quot;&gt;
&lt;em&gt;Each pointer has its own address (&lt;a href=&quot;/blog/default_copy_constructor/dbg_calling_custom_copy_con_full.png&quot;&gt;full screenshot&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There was no more pointer aliasing, and both destructors freed the appropriate
memory without issue:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog/default_copy_constructor/dbg_calling_first_destructor_success.png&quot; alt=&quot;screenshot of msvc local and watch windows after calling the first destructor&quot; title=&quot;State after first destructor was called&quot;&gt;
&lt;em&gt;First destructor successful (&lt;a href=&quot;/blog/default_copy_constructor/dbg_calling_first_destructor_success_full.png&quot;&gt;full screenshot&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog/default_copy_constructor/dbg_calling_second_destructor_success.png&quot; alt=&quot;screenshot of msvc local and watch windows after calling the second destructor&quot; title=&quot;State after second destructor was called&quot;&gt;
&lt;em&gt;Second destructor successful (&lt;a href=&quot;/blog/default_copy_constructor/dbg_calling_second_destructor_success_full.png&quot;&gt;full screenshot&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Lessons Learned&lt;/h3&gt;
&lt;p&gt;In retrospect, the cause of this bug was right before our eyes. Those more
experienced with C++ probably would have recognized it immediately, but it took
us quite a while to even figure out where to look. A number of factors
contributed to this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We assumed that there were no mistakes in the code provided by the professor.
This assumption delayed us significantly. It misdirected our analytical
efforts and limited the questions we asked. In the end, all code is written by
fallible humans (or by code which was in turn written by fallible humans).
Don't assume code is bug free, &lt;em&gt;verify&lt;/em&gt; that it is.&lt;/li&gt;
&lt;li&gt;We initially found Visual Studio's error messages to be quite cryptic, and
made the unfortunate mistake of not closely examining them. If we had put in
a bit more effort, we would have noticed at least 2 valuable hints:&lt;ul&gt;
&lt;li&gt;&quot;Access violation&quot;&lt;/li&gt;
&lt;li&gt;&quot;Heap corruption&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;We weren't familiar with what the compiler does behind the scenes when
constructors and destructors aren't explicitly defined.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Though time consuming and occasionally frustrating, this was a valuable
opportunity to develop skills of careful observation, thoughtful questioning,
and systematic experimentation that are so essential to developing software.
Both student and tutor departed with new knowledge and understanding, and
perhaps a healthy fear of leaving special methods undefined.&lt;/p&gt;
</content>
  </entry>
</feed>
