{"id":46,"date":"1995-08-02T13:39:00","date_gmt":"1995-08-02T13:39:00","guid":{"rendered":"http:\/\/billwake.com\/index.php\/1995\/08\/02\/sorttables-error-log\/"},"modified":"1995-08-02T13:39:00","modified_gmt":"1995-08-02T13:39:00","slug":"sorttables-error-log","status":"publish","type":"post","link":"https:\/\/billwake.com\/sorttables-error-log\/","title":{"rendered":"SortTables Error Log"},"content":{"rendered":"<h2 style=\"text-align: left;\"> SortTables Error Log<\/h2>\n<p>Inspired by Knuth&#8217;s example of &#8220;The Errors of TeX&#8221; in Software &#8211; Practice and Experience. This is an attempt to capture the errors I made in SortTables software; my most common problem is carelessness, especially in reorganizing data structures. <\/p>\n<hr \/>\n<p><b>Date:<\/b> date<br \/><b>Symptom:<\/b> the-symptom<br \/><b>Cause:<\/b> the-cause<br \/><b>Fix:<\/b> the-fix<br \/><b>Lesson:<\/b> the-lesson<\/p>\n<hr \/>\n<p><b>Date:<\/b> 8-2-95<\/p>\n<p><b>Symptom:<\/b> System printed endless series of blank lines.<br \/>Running in the debugger showed it failed in PatternIndex when it<br \/>tried to close the pattern file.<\/p>\n<p><b>Cause:<\/b> Didn&#8217;t note.<\/p>\n<p><b>Fix:<\/b> Didn&#8217;t note.<\/p>\n<p><b>Lesson:<\/b> Didn&#8217;t learn:)<\/p>\n<hr \/>\n<p><b>Date:<\/b> 7-31-95<\/p>\n<p><b>Symptom:<\/b> Assertion violation (iterator had pos==-1). Came<br \/>about after cutting one or more columns in a ListResult.<\/p>\n<p><b>Cause:<\/b> Had started to move from managing the ListResult as<br \/>an array of buckets to a tree of buckets. To do this, had an array<br \/>twice the size needed, with the leaves starting at<br \/>array[num_buckets]. Unfortunately, one of the routines was relying<br \/>on looking at the array starting at array[0].<\/p>\n<p><b>Fix:<\/b> Make it consistently start at 0. Put off tree stuff for<br \/>now.<\/p>\n<p><b>Lesson:<\/b> Don&#8217;t make partial changes in data structure &#8211;<br \/>either finish the new implementation or don&#8217;t put it in.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 7-29-95<\/p>\n<p><b>Symptom:<\/b> &#8220;And&#8221;-ing together several lists showed the list<br \/>always being left all true. At first it looked like the data might<br \/>be that way, but checking more carefully showed that certain bits<br \/>should be left cleared.<\/p>\n<p><b>Cause:<\/b> The <tt>andWith()<\/tt> method was working properly to<br \/>clear bits but not set them. The value (0 or 1) was being<br \/>left-shifted and negated for and-ing in, but when the value was 0,<br \/>there was no bit set to shift, so nothing ever got left out.<\/p>\n<p><b>Fix:<\/b> Change formula to use &#8220;1&#8221; rather than &#8220;value&#8221;.<\/p>\n<p><b>Lesson:<\/b><\/p>\n<ul>\n<li>Watch those formulas. Simple hand-testing of both cases would<br \/>have exposed this.<\/li>\n<li>QA was left out. The <tt>BitVector<\/tt> module had a sample<br \/><tt>main()<\/tt> routine, but that was never updated when the<br \/><tt>andWith()<\/tt> method was added. The simplest test would have<br \/>exposed this.<\/li>\n<\/ul>\n<hr \/>\n<p><b>Date:<\/b> 7-17-95<\/p>\n<p><b>Symptom:<\/b> SortTables locks up &#8211; apparent infinite loop.<\/p>\n<p><b>Cause:<\/b> It was an infinite loop. Had added a<br \/>cList_freeObjects() method, that looked at the last object, for as<br \/>long as there were objects. Since it looked but didn&#8217;t remove the<br \/>object, list never shrank, and it just kept looking.<\/p>\n<p><b>Fix:<\/b> Don&#8217;t just look at the last object, remove it from the<br \/>list.<\/p>\n<p><b>Lesson:<\/b> Watch use of functions with similar names (here<br \/>cList_lastObject() vs. cList_removeLastObject().)<\/p>\n<hr \/>\n<p><b>Date:<\/b> 6-23-95<\/p>\n<p><b>Symptom:<\/b> After switching from &#8220;big&#8221; to &#8220;small&#8221;, the items in<br \/>the small set aren&#8217;t ordered properly.<\/p>\n<p><b>Cause:<\/b> Reset the column # in the new set to 0; should have<br \/>left it at same column # as old set (otherwise throws off display<br \/>and others about where things are; change in rep should be<br \/>transparent to clients).<\/p>\n<p><b>Fix:<\/b> Update that number to proper value.<\/p>\n<p><b>Lesson:<\/b> Make sure every data is set in constructors!<\/p>\n<hr \/>\n<p><b>Date:<\/b> 6-23-95<\/p>\n<p><b>Symptom:<\/b> After shift in representation from &#8220;big&#8221; to<br \/>&#8220;small&#8221;, items in the small set were not in order. Moving<br \/>cursor-down jumped around rather than going one at a time.<br \/>Investigation revealed the table structure in TableResult had<br \/>_ptable[0]==_ptable[1] (not good for a permutation). Added a check<br \/>for this, so it would die the first time that happened. However, in<br \/>the debugger, when TableResult&#8217;s ResultSet-based constructor is<br \/>called, it ends up with suspicious pointers.<\/p>\n<p><b>Cause:<\/b><\/p>\n<ul>\n<li>TableResult had been using the cList class; modified to use a<br \/>simple array. Had assumed that a circular list was necessary, but<br \/>in fact this was never the case. Removed that assumption, so now it<br \/>just assumes an arbitrary starting point.<\/li>\n<li>In the new constructor for TableResult &#8211; had converted it from<br \/>a for-loop-based iterator to a while-loop one. Had the &#8220;next&#8221; at<br \/>the bottom of the loop rather than the top.<\/li>\n<\/ul>\n<p><b>Fix:<\/b><\/p>\n<ul>\n<li>Simplified _ptable to simple list.<\/li>\n<li>Structure the while-loop properly.<\/li>\n<\/ul>\n<p><b>Lesson:<\/b> Need to be very careful on manual code<br \/>transformations.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 6-22-95<\/p>\n<p><b>Symptom:<\/b> Screen repeated blank lines (memory trap in<br \/>debugger).<\/p>\n<p><b>Cause:<\/b> Had set up system to start shifting representations<br \/>when size changed dramatically, by applying Coplien&#8217;s<br \/>letter-envelope idiom. Had changed uses of ResultSet so it was an<br \/>envelope. However &#8211; the result set has an associated iterator that<br \/>must be changed as well.<\/p>\n<p><b>Fix:<\/b> &#8220;Defined the problem away&#8221; by making a rule that Cut or<br \/>Match operations (the destructive ones) invalidate existing<br \/>iterators, thus pushing the problem onto their clients.<\/p>\n<p><b>Lesson:<\/b> Don&#8217;t switch things halfway. Remember that iterators<br \/>and collections are closely tied together. Be careful with<br \/>envelope-client idiom; it&#8217;s what&#8217;s needed here because we&#8217;re<br \/>switching types, but it brings a lot of baggage. Probably better<br \/>off with a separate &#8220;rep&#8221; hierarchy.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 6-21-95<\/p>\n<p><b>Symptom:<\/b> Had converted a set of classes to Coplien&#8217;s<br \/>envelope-letter structure. After trying to do a reload of the data<br \/>(within running program), just started printing blank lines<br \/>&#8220;forever&#8221;. Debugger showed this as dying in the base class<br \/>destructor.<\/p>\n<p><b>Cause:<\/b> Needed to initialize _rep to NULL in &#8220;letter&#8221;<br \/>classes. Otherwise, it has garbage value even though it isn&#8217;t<br \/>used.<\/p>\n<p><b>Fix:<\/b> Set _rep=NULL.<\/p>\n<p><b>Lesson:<\/b> Watch effects on all parts of class data when<br \/>re-organizing.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 6-19-96<\/p>\n<p><b>Symptom:<\/b> SortTables: deleting records before a point didn&#8217;t<br \/>delete any records.<\/p>\n<p><b>Cause:<\/b><\/p>\n<ul>\n<li>Trying to move from a simple array (where deleting required<br \/>copying the array) to an array treated as a circular list. Made<br \/>&#8220;deleteBefore&#8221; parallel to &#8220;deleteAfter&#8221; only it updated the start<br \/>rather than the count. BUT &#8211; deleteBefore changes both start and<br \/>count where deleteAfter really does only affect count.<\/li>\n<li>Also &#8211; when fetching the i-th item, didn&#8217;t take into account<br \/>the starting position.<\/li>\n<li>Also when sorting the list.<\/li>\n<\/ul>\n<p><b>Fix:<\/b> Adjust count as well; return proper position; sort<br \/>proper list.<\/p>\n<p><b>Lesson:<\/b> Could have probably caught this with some invariant.<br \/>BUT &#8211; really need to walk through all class data and make sure of<br \/>which things an operation affects.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 6-16-95<\/p>\n<p><b>Symptom:<\/b> Died in memory allocation. Said the &#8220;record_set&#8221;<br \/>field had a bad value. Examining *this showed it as being ok.<\/p>\n<p><b>Cause:<\/b> Had moved a field from child to parent, but forgot to<br \/>delete it from child.<\/p>\n<p><b>Fix:<\/b> Delete child version.<\/p>\n<p><b>Lesson:<\/b> Watch editing habits!!<\/p>\n<hr \/>\n<p><b>Date:<\/b> 6-16-95<\/p>\n<p><b>Symptom:<\/b> First record wasn&#8217;t shown, last record was blank.<br \/>When moving to other columns, items were scrambled.<\/p>\n<p><b>Cause:<\/b> Had messed up ListIterator to return record numbers<br \/>starting with 1 rather than 0, because the display routine used a<br \/>list that was designed for pointers and couldn&#8217;t store items with<br \/>value 0.<\/p>\n<p><b>Fix:<\/b> Not ideal, but moved the &#8220;encoding&#8221; up to the display<br \/>routine that wanted to use the list. Ideally, we&#8217;d use a list that<br \/>handled integers properly.<\/p>\n<p><b>Lesson:<\/b> Keep hacking isolated to the place where it&#8217;s<br \/>needed. Use proper tools. (Don&#8217;t want to change the List class<br \/>because it works as documented for the NeXT list class; but it<br \/>would be better to have a &#8220;real&#8221; list class for integers.)<\/p>\n<hr \/>\n<p><b>Date:<\/b> 6-15-95<\/p>\n<p><b>Symptom:<\/b> Reading records by looking at offset+length in<br \/>file. What should have been a short field was a long string<br \/>containing more than one record.<\/p>\n<p><b>Cause:<\/b> When writing the file originally, had cut-and-paste<br \/>code to write a proper-endian number. But &#8211; the value to be written<br \/>was in a different variable.<\/p>\n<p><b>Fix:<\/b> Change variable name to match.<\/p>\n<p><b>Lesson:<\/b> Bad symptom &#8211; spreading knowledge of endianness<br \/>around. Watch cut-and-paste.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 6-15-95<\/p>\n<p><b>Symptom:<\/b> Debugging output &#8211; label appeared but rest of<br \/>information didn&#8217;t.<\/p>\n<p><b>Cause:<\/b> Left out a format specifier in printf.<\/p>\n<p><b>Fix:<\/b> Put it in.<\/p>\n<p><b>Lesson:<\/b> Watch printf (as usual). Surprising the compiler<br \/>didn&#8217;t catch it &#8211; it was a constant string, compiled with -Wall.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 5-29-95<\/p>\n<p><b>Symptom:<\/b> Re-loading a file caused a trap.<\/p>\n<p><b>Cause:<\/b> Had created a bitvector from static storage to reduce<br \/>costs of initializing it to all 0&#8217;s. (static data defaults to 0.)<br \/>Had intended to re-clear this storage when object was deleted<br \/>(rather than created) &#8211; but never did.<\/p>\n<p><b>Fix:<\/b> Let &#8220;BitVector&#8221; object allocate the storage<br \/>dynamically; profile to see if it matters. (If so, go back to<br \/>&#8220;clear on delete&#8221;.)<\/p>\n<p><b>Lesson:<\/b> Don&#8217;t put off today&#8230; Profile before worrying about<br \/>efficiency. (Although I think I may have tagged that at one point<br \/>as being a valid efficiency concern.) Keep notes &#8211; use TBD comments<br \/>to record intentions.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 5-12-95<\/p>\n<p><b>Symptom:<\/b> Getting wrong values for min &amp; max<\/p>\n<p><b>Cause:<\/b> Moved min\/max init. code around, but in one that sets<br \/>initial values didn&#8217;t properly change columns while setting them.<br \/>Some lower-level code relied on actual column number to know what<br \/>to fetch, so everything was based on column 0.<\/p>\n<p><b>Fix:<\/b> Add next_column() and reset_column() calls.<\/p>\n<p><b>Lesson:<\/b> Watch initialization.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 5-8-95<\/p>\n<p><b>Symptom:<\/b> Triggered assertion violation in display.cc.<\/p>\n<p><b>Cause:<\/b> Added _col_is_restricted to decide whether I had an<br \/>exact or approximate count, set true whenever _bounds_xxx[]<br \/>changed, and tested on each loop over them. BUT: this precluded<br \/>adjusting the bounds when a column changed.<\/p>\n<p><b>Fix:<\/b> Change so that counting adjusted columns is independent<br \/>of bounds[] setting. Now _col_is_restricted[] tells whether there<br \/>was an explicit restriction on THIS column.<\/p>\n<p><b>Lesson:<\/b> Things keep getting caught in display.cc; but the<br \/>problem is happening in the interaction between ListResult.cc and<br \/>ListIterator.cc. Need something that can move the assertions back<br \/>down there to catch problem closer to point of call.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 5-8-95<\/p>\n<p><b>Symptom:<\/b> Complaints about undefined externs<br \/>&#8220;read\/open\/etc&#8221;.<\/p>\n<p><b>Cause:<\/b> Choosing header files is tricky. Part of the problem<br \/>is inconsistency &amp; non-standard choices.<\/p>\n<p><b>Fix:<\/b> Ensure that &#8220;Universal_include.h&#8221; is the first<br \/>inclusion in each .cc.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 5-8-95<\/p>\n<p><b>Symptom:<\/b> Triggered an assertion violation in display.cc.<\/p>\n<p><b>Cause:<\/b> Adding PositionPool: set up a default size of<br \/>LISTRESULT_MAX_DIMS for size of cached items. Unfortunately, file<br \/>was organized by size being the current actual number of<br \/>columns.<\/p>\n<p><b>Fix:<\/b> Make PositionPool request FileArray of the proper<br \/>size.<\/p>\n<p><b>Lesson:<\/b> Tough one. Need fixed-size entities for performance<br \/>reasons, but variable-sized ones out on disk. Need to think this<br \/>through.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 5-3-95<\/p>\n<p><b>Symptom:<\/b> Moved system to Alpha, didn&#8217;t work. Problems on<br \/>very large data set on ei.cs.<\/p>\n<p><b>Cause:<\/b> Same problem again: had a couple &#8220;long&#8221;s in place.<br \/>The real cause is poor configuration management: changes on fir\/ST5<br \/>were not put back into jingluo\/ST5, and jingluo\/ST5 become<br \/>jingluo\/ST6 with &#8220;old&#8221; code.<\/p>\n<p><b>Fix:<\/b> Redo repairs; check diffs.<\/p>\n<p><b>Lesson:<\/b> Better config mgmt.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 3-2-95<\/p>\n<p><b>Symptom:<\/b> Moved system to Alpha (64-bit int), didn&#8217;t<br \/>work.<\/p>\n<p><b>Cause:<\/b> Used &#8220;long&#8221; and &#8220;int&#8221; for types w\/assumed 32-bit<br \/>sizes. Had also used &#8220;raw&#8221; machine order to write binary files.<\/p>\n<p><b>Fix:<\/b> Define length-specific types depending on system. Use<br \/>ntohl() and htonl() to define FROM_BIG_INT32() and TO_BIG_INT32()<br \/>macros. (Probably not good names).<\/p>\n<p><b>Lesson:<\/b> Ongoing problem with C types. Almost always get pain<br \/>from depending on raw types. Need smoother handling of binary I\/O.<br \/>(Changed to convert on fly here, probably shouldn&#8217;t do unless<br \/>necessary.)<\/p>\n<hr \/>\n<p><b>Date:<\/b> 2-27-95<\/p>\n<p><b>Symptom:<\/b> Tried to substitute a &#8220;word wrapping&#8221; window for<br \/>item display in sorttables. Random words appeared everywhere in<br \/>window.<\/p>\n<p><b>Cause:<\/b> Had put a &#8220;break&#8221; in for debugging; this caused only<br \/>1 line to be attempted for display. Tried to display line via a<br \/>count &#8220;MAXLINES&#8221;, but didn&#8217;t check actual length of screen, so was<br \/>grabbing random characters.<\/p>\n<p><b>Fix:<\/b> Remove break. Check length first.<\/p>\n<p><b>Lesson:<\/b> Be careful with debugging code. Maybe always add a<br \/>comment &#8220;\/\/ DEBUG&#8221; to the end of the line. Be a little more ready<br \/>to use the debugger rather than dropping into code mods.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 2-24-95<\/p>\n<p><b>Symptom:<\/b> Deleted all but those records starting with &#8220;c&#8221;.<br \/>Was ok. Moved to the end. Died when moving directly back to the<br \/>front.<\/p>\n<p><b>Cause:<\/b> &#8220;prevFor&#8221; routine computed a loop moving back through<br \/>list but tested the original argument rather than the working value<br \/>that was being modified in the loop. (Lucky it wasn&#8217;t an infinite<br \/>loop.)<\/p>\n<p><b>Fix:<\/b> Test right thing in loop.<\/p>\n<p><b>Lesson:<\/b> This came from leaving &#8220;dead&#8221; variables around from<br \/>the parameter. I&#8217;ve tended to treat parameters as &#8220;read-only&#8221;.<br \/>Maybe I should revise that. This is sort of a const-correctness<br \/>issue too &#8211; the parameter in question wasn&#8217;t marked const though<br \/>there was no intent to change it. Finally &#8211; it&#8217;s funny the compiler<br \/>didn&#8217;t notice and warn that loop control could never change.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 2-24-95<\/p>\n<p><b>Symptom:<\/b> After deleting lines, the approximate factor went<br \/>up by a huge amount.<\/p>\n<p><b>Cause:<\/b> Used &#8220;%&#8221; instead of &#8220;\/&#8221; to round off.<\/p>\n<p><b>Fix:<\/b> Use &#8220;\/&#8221;.<\/p>\n<p><b>Lesson:<\/b> Check math functions manually.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 2-24-95<\/p>\n<p><b>Symptom:<\/b> Searching for &#8220;1&#8221; in the year column, with a bunch<br \/>of blank entries first, it didn&#8217;t move until &#8220;199&#8221; was typed even<br \/>though &#8220;1888&#8221; was in the list first.<\/p>\n<p><b>Cause:<\/b> Comparison function in binary search &#8211; took min of<br \/>two lengths, when it really should have considered the whole<br \/>pattern.<\/p>\n<p><b>Fix:<\/b> Don&#8217;t take min.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 2-24-95<\/p>\n<p><b>Symptom:<\/b> Final &#8220;statistics&#8221; output showed objects not<br \/>deleted. This happened when &#8220;@&#8221; was used to re-load a file.<\/p>\n<p><b>Cause:<\/b> The re-load routine created a new result set and<br \/>iterator but didn&#8217;t delete any old ones.<\/p>\n<p><b>Fix:<\/b> Use calloc of initial space to ensure empty pointers,<br \/>make re-load delete old before creating new.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 2-13-95<\/p>\n<p><b>Symptom:<\/b> Computing min and max for a series of buckets which<br \/>are permutations of record numbers. But when running, got an error<br \/>about finding a record which was already in an unchanged list.<br \/>Checked min-max list, and found that after the first column&#8217;s worth<br \/>of buckets, all buckets had same min-max values. (Shouldn&#8217;t be<br \/>possible since it&#8217;s a permutation.)<\/p>\n<p><b>Cause:<\/b> Computed bucket number wrong (should have been<br \/>i*columns not i*columns*capacity).<\/p>\n<p><b>Fix:<\/b> Change computation.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 2-13-95<\/p>\n<p><b>Symptom:<\/b> Computing min and max for a series of buckets which<br \/>are permutations of record numbers. But when running, got an error<br \/>about finding a record which was already in an unchanged list.<br \/>Checked min-max list, and found that after the first column&#8217;s worth<br \/>of buckets, all buckets had same min-max values. (Shouldn&#8217;t be<br \/>possible since it&#8217;s a permutation.)<\/p>\n<p><b>Cause:<\/b> Realized that if I had a bucket only partially<br \/>filled, I would be trying to look up bucket #-1 which can&#8217;t<br \/>exist.<\/p>\n<p><b>Fix:<\/b> Added assertion code to FileArray to ensure only valid<br \/>indexes used, changed calling code to detect &#8220;-1&#8221; and skip that<br \/>non-record. BUT: This doesn&#8217;t affect the original problem.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 2-13-95<\/p>\n<p><b>Symptom:<\/b> Getting a bucket for which max &lt; min; bucket is<br \/>completely filled with -1 values.<\/p>\n<p><b>Cause:<\/b> In figuring left-over &#8220;-1&#8221; values to write to bucket,<br \/>didn&#8217;t consider case that last bucket filled in perfectly.<\/p>\n<p><b>Fix:<\/b> Test for exactly-full bucket.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 2-3-95<\/p>\n<p><b>Symptom:<\/b> Destructor didn&#8217;t run right.<\/p>\n<p><b>Cause:<\/b> Had added a new parent class with a definition<br \/>&#8220;virtual ~EnvoyFactory () = 0;&#8221;. But destructors should not be<br \/>abstract.<\/p>\n<p><b>Fix:<\/b> Change &#8220;=0;&#8221; to &#8220;{}&#8221;.<\/p>\n<p><b>Lesson:<\/b> Spend a little more time learning C++. Would have<br \/>been nice to have a compiler warning on that one.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 2-2-95<\/p>\n<p><b>Symptom:<\/b> Line put on screen didn&#8217;t get put in list of<br \/>displayed lines. This caused the system to allow backward scrolling<br \/>(&#8220;haven&#8217;t hit that line yet&#8221;).<\/p>\n<p><b>Cause:<\/b> List object was designed for pointer objects, and<br \/>assumed NULL could never be put in list. Using it for int objects,<br \/>where value 0 was legal and occurred.<\/p>\n<p><b>Fix:<\/b> Don&#8217;t let 0 occur; add 1 to value before letting it out<br \/>to clients, subtract 1 on use.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 1-20-95<\/p>\n<p><b>Symptom:<\/b> Screen just keeps dumping blank lines.<\/p>\n<p><b>Cause:<\/b> Trying to introduce a new &#8220;iter&#8221; variable. Had<br \/>prototyped it with a simple global. Then tried to pass right iter<br \/>around, but left it off an argument list, so it picked up the<br \/>defunct (un-initialized) global one.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 1-20-95<\/p>\n<p><b>Symptom:<\/b> Lines not displaying right when moving just off<br \/>screen. Should scroll one line but didn&#8217;t scroll at all until two<br \/>down-arrows; might have corrupted some of screen data with wrong<br \/>line, too.<\/p>\n<p><b>Cause:<\/b> Deleted old line from list, used &#8220;count()-1&#8221; to tell<br \/>where new line should be, then added new line to list.<\/p>\n<p><b>Fix:<\/b> Since list was reduced in size already, should have<br \/>used &#8220;count()&#8221; instead.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 1-4-95<\/p>\n<p><b>Symptom:<\/b> Program seemed to run OK but complained when<br \/>deleting an array at the end.<\/p>\n<p><b>Cause:<\/b> The sort comparison for a qsort was backwards; result<br \/>of the sort was compared assuming &#8220;ascending&#8221; but sort yielded<br \/>&#8220;descending&#8221;. This was causing storage to get trashed.<\/p>\n<hr \/>\n<p><b>Date:<\/b> 1-4-95<\/p>\n<p><b>Symptom:<\/b> Sorted items appeared out of order.<\/p>\n<p><b>Cause:<\/b> Sorting was done on an illegal field. The field<br \/>counter should have been wrapped to 0 when it reached the maximum,<br \/>but was incremented instead.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>SortTables Error Log Inspired by Knuth&#8217;s example of &#8220;The Errors of TeX&#8221; in Software &#8211; Practice and Experience. This is an attempt to capture the errors I made in SortTables software; my most common problem is carelessness, especially in reorganizing data structures. Date: dateSymptom: the-symptomCause: the-causeFix: the-fixLesson: the-lesson Date: 8-2-95 Symptom: System printed endless series [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[10,13,11,14],"tags":[],"class_list":["post-46","post","type-post","status-publish","format-standard","hentry","category-dissertation","category-refactoring","category-sorttables","category-testing"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>SortTables Error Log - Bill Wake&#039;s Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"http:\/\/billwake.com\/sorttables-error-log\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"SortTables Error Log - Bill Wake&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"SortTables Error Log Inspired by Knuth&#8217;s example of &#8220;The Errors of TeX&#8221; in Software &#8211; Practice and Experience. This is an attempt to capture the errors I made in SortTables software; my most common problem is carelessness, especially in reorganizing data structures. Date: dateSymptom: the-symptomCause: the-causeFix: the-fixLesson: the-lesson Date: 8-2-95 Symptom: System printed endless series [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"http:\/\/billwake.com\/sorttables-error-log\/\" \/>\n<meta property=\"og:site_name\" content=\"Bill Wake&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"1995-08-02T13:39:00+00:00\" \/>\n<meta name=\"author\" content=\"Bill Wake\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Bill Wake\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"http:\\\/\\\/billwake.com\\\/sorttables-error-log\\\/#article\",\"isPartOf\":{\"@id\":\"http:\\\/\\\/billwake.com\\\/sorttables-error-log\\\/\"},\"author\":{\"name\":\"Bill Wake\",\"@id\":\"https:\\\/\\\/billwake.com\\\/#\\\/schema\\\/person\\\/b551cc572ce5d025b081e031a73eec0c\"},\"headline\":\"SortTables Error Log\",\"datePublished\":\"1995-08-02T13:39:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"http:\\\/\\\/billwake.com\\\/sorttables-error-log\\\/\"},\"wordCount\":2635,\"commentCount\":0,\"articleSection\":[\"dissertation\",\"refactoring\",\"SortTables\",\"testing\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"http:\\\/\\\/billwake.com\\\/sorttables-error-log\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"http:\\\/\\\/billwake.com\\\/sorttables-error-log\\\/\",\"url\":\"http:\\\/\\\/billwake.com\\\/sorttables-error-log\\\/\",\"name\":\"SortTables Error Log - Bill Wake&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/billwake.com\\\/#website\"},\"datePublished\":\"1995-08-02T13:39:00+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/billwake.com\\\/#\\\/schema\\\/person\\\/b551cc572ce5d025b081e031a73eec0c\"},\"breadcrumb\":{\"@id\":\"http:\\\/\\\/billwake.com\\\/sorttables-error-log\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\\\/\\\/billwake.com\\\/sorttables-error-log\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\\\/\\\/billwake.com\\\/sorttables-error-log\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/billwake.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"SortTables Error Log\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/billwake.com\\\/#website\",\"url\":\"https:\\\/\\\/billwake.com\\\/\",\"name\":\"Bill Wake&#039;s Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/billwake.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/billwake.com\\\/#\\\/schema\\\/person\\\/b551cc572ce5d025b081e031a73eec0c\",\"name\":\"Bill Wake\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8e2b28fe375cac050dad2f141da886dde7ff7a1edc00116f801ec96cf3849fa1?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8e2b28fe375cac050dad2f141da886dde7ff7a1edc00116f801ec96cf3849fa1?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/8e2b28fe375cac050dad2f141da886dde7ff7a1edc00116f801ec96cf3849fa1?s=96&d=mm&r=g\",\"caption\":\"Bill Wake\"},\"url\":\"https:\\\/\\\/billwake.com\\\/author\\\/bill-wake\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"SortTables Error Log - Bill Wake&#039;s Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"http:\/\/billwake.com\/sorttables-error-log\/","og_locale":"en_US","og_type":"article","og_title":"SortTables Error Log - Bill Wake&#039;s Blog","og_description":"SortTables Error Log Inspired by Knuth&#8217;s example of &#8220;The Errors of TeX&#8221; in Software &#8211; Practice and Experience. This is an attempt to capture the errors I made in SortTables software; my most common problem is carelessness, especially in reorganizing data structures. Date: dateSymptom: the-symptomCause: the-causeFix: the-fixLesson: the-lesson Date: 8-2-95 Symptom: System printed endless series [&hellip;]","og_url":"http:\/\/billwake.com\/sorttables-error-log\/","og_site_name":"Bill Wake&#039;s Blog","article_published_time":"1995-08-02T13:39:00+00:00","author":"Bill Wake","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Bill Wake","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"http:\/\/billwake.com\/sorttables-error-log\/#article","isPartOf":{"@id":"http:\/\/billwake.com\/sorttables-error-log\/"},"author":{"name":"Bill Wake","@id":"https:\/\/billwake.com\/#\/schema\/person\/b551cc572ce5d025b081e031a73eec0c"},"headline":"SortTables Error Log","datePublished":"1995-08-02T13:39:00+00:00","mainEntityOfPage":{"@id":"http:\/\/billwake.com\/sorttables-error-log\/"},"wordCount":2635,"commentCount":0,"articleSection":["dissertation","refactoring","SortTables","testing"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["http:\/\/billwake.com\/sorttables-error-log\/#respond"]}]},{"@type":"WebPage","@id":"http:\/\/billwake.com\/sorttables-error-log\/","url":"http:\/\/billwake.com\/sorttables-error-log\/","name":"SortTables Error Log - Bill Wake&#039;s Blog","isPartOf":{"@id":"https:\/\/billwake.com\/#website"},"datePublished":"1995-08-02T13:39:00+00:00","author":{"@id":"https:\/\/billwake.com\/#\/schema\/person\/b551cc572ce5d025b081e031a73eec0c"},"breadcrumb":{"@id":"http:\/\/billwake.com\/sorttables-error-log\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["http:\/\/billwake.com\/sorttables-error-log\/"]}]},{"@type":"BreadcrumbList","@id":"http:\/\/billwake.com\/sorttables-error-log\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/billwake.com\/"},{"@type":"ListItem","position":2,"name":"SortTables Error Log"}]},{"@type":"WebSite","@id":"https:\/\/billwake.com\/#website","url":"https:\/\/billwake.com\/","name":"Bill Wake&#039;s Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/billwake.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/billwake.com\/#\/schema\/person\/b551cc572ce5d025b081e031a73eec0c","name":"Bill Wake","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/8e2b28fe375cac050dad2f141da886dde7ff7a1edc00116f801ec96cf3849fa1?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/8e2b28fe375cac050dad2f141da886dde7ff7a1edc00116f801ec96cf3849fa1?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8e2b28fe375cac050dad2f141da886dde7ff7a1edc00116f801ec96cf3849fa1?s=96&d=mm&r=g","caption":"Bill Wake"},"url":"https:\/\/billwake.com\/author\/bill-wake\/"}]}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/billwake.com\/wp-json\/wp\/v2\/posts\/46","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/billwake.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/billwake.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/billwake.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/billwake.com\/wp-json\/wp\/v2\/comments?post=46"}],"version-history":[{"count":0,"href":"https:\/\/billwake.com\/wp-json\/wp\/v2\/posts\/46\/revisions"}],"wp:attachment":[{"href":"https:\/\/billwake.com\/wp-json\/wp\/v2\/media?parent=46"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/billwake.com\/wp-json\/wp\/v2\/categories?post=46"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/billwake.com\/wp-json\/wp\/v2\/tags?post=46"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}