Nicolai M. Josuttis: solutions in time  The C++ Standard Library: Errata for 5th to 13th printings

The C++ Standard Library - A Tutorial and Reference

Errata for the 5th to 13th printings
Jul 25, 2004

This is the errata for the 5th to 13th printings of the book The C++ Standard Library by Nicolai M. Josuttis. It extends the errata for the previous printings.Thus, you will find additional errors in the erratas for later printings.
Please, note the
- hints for Visual C++ users.
- hints for GCC/G++ users.

The errata is organized in the following way:
- The first part lists technical errors
- The second part lists typos

Please note: This list may portray the book as containing many errors. But keep in mind that the book has about 800 pages with about 240.000 words. As I am not perfect I couldn't do better, and in my opinion it is severe to expect significantly fewer bugs. To cite one reader: "Thanks again and I'm going to write a short review of the book for Amazon contradicting whoever said it had lots of errors."


Errors

Page 54, Section 4.2.6
For auto_ptr::release() one bullet is missing:
    - Sets the value of the auto_ptr to zero.


Page 61, Table 4.2:
min() returns for floating point-types the minimum positive normalized value.


Page 100, Section 5.4.1
The algorithm to find the order of two values inside a collection does not handle the case that one or both might be missing correctly. The correct version is as follows:

pos25 = find (coll.begin(), coll.end(),    // range
              25);                         // value
pos35 = find (coll.begin(), pos25,         // range
              35);                         // value
if (pos25 != coll.end() && pos35 != pos25) {
    /* pos35 is in front of pos25
     * so, only [pos35,pos25) is valid
     */
    ...
}
else {
    pos35 = find (pos25, coll.end(),       // range
                  35);                     // value
    if (pos35 != coll.end()) {
        /* pos25 is in front of pos35
         * so, only [pos25,pos35) is valid
         */
        ...
    }
    else {
        // 25 and/or 35 not found
        ...
    }
}


Page 101, Section 5.4.1
The switch statement dereferences pos, which is an error if pos is coll.end(). Thus, the statements after calling find_if() have to be as follows:

if (pos == coll.end()) {
    // no element with value 25 or 35 found
    ...
}
else if (*pos == 25) {
    // element with value 25 comes first
    pos25 = pos;
    pos35 = find (++pos, coll.end(),    // range
                  35);                  // value
    ...
}
else {
    // element with value 35 comes first
    pos35 = pos;
    pos25 = find (++pos, coll.end(),    // range
                  25);                  // value
    ...
}


Page 107, Section 5.5.2
In stl
/ioiter1.cpp the header file for stream iterators is missing:
    #include <iterator>


Page 109, Section 5.5.3
In stl
/riter1.cpp the header file for stream iterators is missing:
    #include <iterator>


Page 111, 112, 115, Section 5.6.1, 5.6.2
In stl/remove1.cpp, stl/remove2.cpp, and stl
/remove3.cpp the header file for stream iterators is missing:
    #include <iterator>


Page 122, Section 5.8.2
By definition, 0 and 1 are not prime numbers. Thus, for these values isPrime() should return false instead of true.


Page 124, Section 5.8.2
In stl/sort1.cpp, the sorting criterion in personSortCriterion() is wrong. It has to return:
 return p1.lastname()<p2.lastname() ||
        (p1.lastname()==p2.lastname() &&
         p1.firstname()<p2.firstname());


Page 135, Section 5.10.2
The sentence "All containers create internal copies of their elements and return copies of those elements.” is not correct. In fact, the member functions at(), front(), back(), and operator [] return references if available.


Page 140, Section 5.11.2
The auxiliary insert() function does not work because we use pos (as iterator of coll) as iterator for an insertion into tmp. Thus, the second line inside insert() has to be as follows:
    coll.insert(pos,value); // modify


Page 156, Section 6.2.5
In cont/vector1.cpp the header file for stream iterators is missing:
    #include <iterator>


Page 159, Section 6.2.6
At the end of the definition of class std::vector<bool>::reference right in the middle of page 159 there is a semicolon missing.


Page 159, Section 6.2.6
In the example at the bottom of the page, Substitute c.at(5) by c[5] because in contrast to the following text c.at(5) would throw an exception instead of causing undefined behavior if no sixth element exists.


Page 164, Section 6.3.4
In cont/deque1.cpp the header file for stream iterators is missing:
    #include <iterator>


Page 172, Section 6.4.4
In cont/list1.cpp the header file for stream iterators is missing:
    #include <iterator>


Page 176, Section 6.5:
For the definition of strict weak ordering a fourth property is missing:

4. It has to have transitivity of equivalence, which
means roughly: If a is equivalent to b and b is equivalent to c, then a is equivalent to c.
 This means for operator <: If !(a<b) && !(b<a) is true and !(b<c) && !(c<b) is true then !(a<c) && !(c<a) is true.
 This means for a predicate op(): If op(a,b), op(b,a), op(b,c), and op(c,b) all yield false then op(a,c) and op(c,a) yield false.


Page 186, Section 6.5.4
In cont/set1.cpp the header files for algorithms and stream iterators are missing:
    #include <algorithm>
    #include <iterator>


Page 189, Section 6.5.4
In cont/mset1.cpp the header files for algorithms and stream iterators are missing:
    #include <algorithm>
    #include <iterator>


Page 197, Section 6.6.2
In the definition of StringFloatMap, the second occurrence of string also has to get qualified by std::.


Page 202, Section 6.6.2
In Table 6.31 replace
    c.erase(elem)  |   Removes all elements with value elem and returns the number of removed elements
by
    c.erase(key)    |   Removes all elements with key and returns the number of removed elements


Page 209, Section 6.6.5
In the output of cont/map1.cpp the tabulator characters were replaced by spaces.


Page 218, Section 6.7.2
In cont/array1.cpp the header files for stream iterators is missing:
    #include <iterator>


Page 228/229, Section 6.9
In cont/sortset.cpp and cont/sortvec.cpp the header file for stream iterators are missing:
    #include <iterator>
In addition, please note the hints for gcc/g++ users.


Page 234, Section 6.10.3
container::count() has logarithmic complexity.


Page 257, Section 7.2.5
last sentence: replace "even number" by "odd number"


Page 282, Section 7.4.3
In iter/advance2.cpp the header file for stream iterators is missing:
    #include <iterator>


Page 295, Section 8.1.1
In fo/sort1.cpp, the sorting criterion PersonSortCriterion is wrong. It has to return:
 return p1.lastname()<p2.lastname() ||
        (p1.lastname()==p2.lastname() &&
         p1.firstname()<p2.firstname());


Page 311/312, Section 8.2.4
In fo/fopow1.cpp the header file for stream iterators is missing:
    #include <iterator>
In addition, the ostream_iterator has to be instanciated for float. Thus, in both calls the 3rd parameter for transform() has to be: ostream_iterator<float>(cout," ")


Page 332, Section 9.3
In algo/algostuff.hpp the header file for stream iterators is missing:
    #include <iterator>


Page 339 and 340, Section 9.5.2
For all arguments and return types min_element() and max_element() have ForwardIterator instead of InputIterator.


Page 344, Section 9.5.3
For all arguments and return types both forms of search_n() have ForwardIterator instead of InputIterator.


Page 354, Section 9.5.3
For all arguments and return types both forms of adjacent_find() have ForwardIterator instead of InputIterator.


Page 360, Section 9.5.4

The complexity of lexicographical_compare() incorrectly has a factor of 2. Thus, replace
    2*min(numberOfElements1,numberOfElements2)
by
    min(numberOfElements1,numberOfElements2)


Page 366, Section 9.6.1
In algo/copy3.cpp the header file for stream iterators is missing:
    #include <iterator>


Page 380, Section 9.7.1
The descriptions of remove_copy() and remove_copy_if() are misleading.
Replace the second sentence of the first item by:

It copies each element in the source range [beg,end) that is not equal to value into the destination range starting with destBeg.

Replace the second sentence of the second item by:

It copies each element in the source range [beg,end) for which the unary predicate op(elem) yields false into the destination range starting with destBeg


Page 385, Section 9.7.2
In algo/unique3.cpp the header file for stream iterators is missing:
    #include <iterator>


Page 391, Section 9.8.3
!!!
There are two forms of next_permutation() and prev_permutation() missing where you can submit the sorting criterion as third argument. The argument has to be a binary predicate as for lexicographical_compare() on page 360.


Page 429, Section 9.11.1
Swap comments on top as follows:
                multiplies<int>(),     
// outer operation
                plus<int>())           // inner operation


Page 448, Section 10.2.3

Replace
    explicit queue::stack (const Container& cont)
by
    explicit queue::queue (const Container& cont)


Page 457, Section 10.3.3
Remove the semicolon between the parameter list and function body of push().


Page 471, Section 11
Saying that the type of string literals is const char* ist not quite right. Strictly speaking, the original type of a literal such as "hello" is const char[6]. However, this type automatically converts ("decays") to const char*, so that you can almost always use (and see) const char* in declarations. However, when working with templates the difference might matter because for reference template parameters decay doesn't occur (see our new template book :-).


Page 481, Section 11.2.2
Replace
    copy()    |    Copies or writes contents to a C-String
by
    copy()    |    Copies or writes contents to a character array


Page 492, Section 11.2.10
Item "1.": Operator >> skips whitespace if the skipws flag is set; thus, strike "not".


Page 502, Section 11.2.13
In string/unique.cpp the header file for stream iterators is missing:
    #include <iterator>


Page 512, Section 11.3.5
Operator[] for constants has return type const char& instead of char.


Page 518, Section 11.3.7
The string::erase() functions for iterator arguments return iterators. Thus, twice replace string& by iterator and replace in the second bullet "They return the first character" by "They return the position of the first character".


Page 547, Section 12.2
For the Blitz web site see: http://www.oonumerics.org/blitz/. In addition, see http://www.oonumerics.org for many other useful sites and links about numeric processing in C++.


Page 553, Section 12.2.1
In num/val2.cpp vc has to be defined with 9 as initial size:
    valarray<double> vc(9);


Page 617, Section 13.7.2
In the example at the bottom, all identifiers except b have to get qualified by std::.


Page 622, Section 13.7.5
In the example after Table 13.20 you have to replace std::ios::hex by std::hex and std::ios::dec by std::dec. Otherwise, instead of changing the base the value of the flags are written.


Page 670, Section 13.13.3
In io/outbuf1x.hpp, you have to qualify int_type as subtype of traits. This is because names in template argument dependent base classes are not found when the class template is defined. Thus, twice replace int_type by typename traits::int_type.


Page 673, Section 13.13.3
In io/outbuf2.hpp, the constructor of class fdostream is buggy because &buf is passed to the ostream constructor before buf is initialized. This might cause a core dump. The correct implementation is as follows:
    fdostream (int fd) : std::ostream(0), buf(fd) {
        rdbuf(&buf);
    }
Instead, you might use Ron's Member Idiom.


Page 678 and 679, Section 13.13.3
In io/inbuf1.hpp:

In underflow(), the return statements have to be as follows:
    
return traits_type::to_int_type(*gptr());
instead of:
    return *gptr();
Otherwise, it might happen that the return value is promoted to EOF by accident.

In addition, memmove() has to be used instead of memcpy() because it might happen that source and destination area overlap.


Page 706, Section 14.4.1
For the initialization of np there is a > missing. The correct statement has to be:
  //
get numeric output facet of the loc locale
  const std::num_put<charT,OutIt>& np
     = std::use_facet<std::num_put<charT,OutIt> >(loc);


Page 727, Section 15.1
Fix the type definitions as follows (std:: in front of basic_string and "> >" instead of ">>" before xmap):

// special string type that uses special allocator
typedef std::basic_string<char,std::char_traits<char>,
                          MyAlloc<char> > xstring;

// special string/string map type that uses special allocator
typedef std::map<xstring,xstring,less<xstring>,
                 MyAlloc<std::pair<const xstring,xstring> > > xmap;

Note: In older printings MyAlloc was named SpecialAlloc.


Page 728, Section 15.2
In Table 15.1, the second row has to be as follows:

a.construct(p,val)    |    Initializes the element to which p refers with val


Page 747, Index

Insert:

Note: Page numbers in bold indicate the location of the definition of the
item. Page numbers in the normal type face are other pages of interest. If
the entry appears in source code the page numbers are in the italic type
face.


Typos

Page 7: s/International Standards Organization/International Organization for Standardization/

Page 19: s/p did not refer to an object of type Cabriolet/cp did not refer to an object of type Cabriolet/

Page 20: s/It may be but is not required to reinterpret bits/It may reinterpret bits, but it is not required to do so/

Page 29: s/The C-string, returned by what, is/The C-string returned by what is/

Page 29: s/due to a bad_alloc exception,/when a bad_alloc exception is thrown/

Page 29: s/The specification of the lifetime/The lifetime/

Page 30: s/Deriving Standard Exception Classes/Deriving from Standard Exception Classes/

Page 35: s/void foo {/void foo() {/

Page 36: s/void foo {/void foo() {/

Page 44: s/This might result in a memory leak if, for example,/This will result in a memory leak if/

Page 45: s/ClassB (ClassA val1, ClassA val2)/ClassB (const ClassA& val1, const ClassA& val2)/

Page 60: s/static T min() throw() {/static int min() throw() {/
Page 60: s/
static T max() throw() {/static int max() throw() {/

Page 81: s/in Chapter 11)./in Chapter 11./

Page 90: s/set container for/container for/

Page 99: s/is in NOT/is NOT in/

Page 99: s/things are getting more complicated/things get more complicated/

Page 140: s/detailled/detailed/

Page 150: s/Table 6.2: Constructors and Destructors of Vectors/Table 6.2: Constructors and Destructor of Vectors/

Page 151: in Table 6.3: s/capacity()/c.capacity()/

Page 151: in Table 6.3: s/reserve()/c.reserve(num)/

Page 153: s/However, for vectors they are often ordinary pointers./However, for vectors the iterators returned by begin() and end() are often ordinary pointers./

Page 156: s/erase() and clear/erase() and clear()/

Page 158, Table 6.8: s/m/c/ (four times)

Page 176, Footnote 17: s/shortest path to an element/shortest path to a leaf/

Page 191: s/comparision/comparison/ (twice)

Page 230: s/pair <const key-type, value-type>/pair <const key-type, mapped-type>/

Page 238: s/make_pair(x,T())/make_pair(key,T())/

Page 252: in Table 7.1: s/vector,deque/vector,deque,/

Page 313: s/In principal/In principle/

Page 322: s/You can pass a function or function objects that specify/You can pass a function or function object that specifies/ (twice)

Page 326:s/elements of associative algorithms/elements of associative containers/

Page 344: s/find()/find_if()/ (twice)

Page 345: s/searches for three consecutive elements/searches for four consecutive elements/

Page 385: s/print element with consecutive/print elements with consecutive/

Page 385: s/print element without consecutive duplicates/print elements without consecutive entries/

Page 436: s/internally by the queue/internally by the stack/

Page 446: s/front() and back() return the next element/front() and back() return the element/

Page 474: s/searches the first occurrence/searches for the first occurrence/

Page 482, Table 11.2: s/size_type num/size_type num/ (just the font)

Page 493: s/arbitray character/arbitrary character/

Page 494: s/the value that is searched./the value that is searched for./

Page 509: s/Note that cstr may not be/Note that cstr must not be/

Page 517: s/Both forms return *this./The first form returns *this./

Page 525: s/strm.good()/strm.good()/ (just the font, twice)

Page 585: s/Section 14/Chapter 14/

Page 593: s/ostream and wstream/ostream and wostream/

Page 602: s/an exceptions is thrown/an exception is thrown/

Page 608 and 609: s/read(s) ... characters in the/read(s) ... characters into the/ (three times)

Page 622, Table 13.20: swap the meaning of dec and hex

Page 638: s/Section 3, page 683/Section 13.14.2, page 683/

Page 686: s/just 1 byte for locales, where/just 1 byte for locales where/


Home of the C++ Library book