/* gcc -Wall -Wextra -std=c++11 copy_n_vs_copy.cpp -lstdc++ -o copy_n_vs_copy
One Past the End https://gcc.gnu.org/onlinedocs/libstdc++/manual/iterators.html#iterators.predefined.end BUG location: /usr/lib/gcc/x86_64-pc-linux-gnu/5.1.0/include/g++-v5/bits/stl_algo.h */ #include <assert.h> #include <iostream> #include <sstream> #include <algorithm> int main() { std::string i("abc"); std::string o; std::istringstream t; t=std::istringstream(i); o.clear(); assert(3==t.rdbuf()->in_avail()); std::copy(std::istreambuf_iterator<char>(t.rdbuf()), std::istreambuf_iterator<char>(),back_inserter(o)); std::cout<<"Test1(copy):\tResult_size:"<<o.size()<<"\tResult:\""<<o <<"\"\tin_avail:"<<t.rdbuf()->in_avail()<<std::endl; assert(0==t.rdbuf()->in_avail()); /* OK! */ t=std::istringstream(i); o.clear(); assert(3==t.rdbuf()->in_avail()); std::copy_n(std::istreambuf_iterator<char>(t.rdbuf()), 3,back_inserter(o)); std::cout<<"Test2(copy_n):\tResult_size:"<<o.size()<<"\tResult:\""<<o <<"\"\tin_avail:"<<t.rdbuf()->in_avail()<<std::endl; assert(1==t.rdbuf()->in_avail()); /* WHY? */ return(0); } /* Test1(copy): Result_size:3 Result:"abc" in_avail:0 Test2(copy_n): Result_size:3 Result:"abc" in_avail:1 */
--- /usr/lib/gcc/x86_64-pc-linux-gnu/5.1.0/include/g++-v5/bits/stl_algo.h 2015-02-19 20:57:40.000000000 +0000 +++ /usr/lib/gcc/x86_64-pc-linux-gnu/5.1.0/include/g++-v5/bits/stl_algo.h 2015-02-19 20:57:40.000000000 +0000 @@ -762,9 +762,8 @@ { *__result = *__first; ++__result; - if (--__n > 0) - ++__first; - else + ++__first; + if (--__n <= 0) break; } }