I was just curious how some of the C++ algorithms check the range of the result/output container when you only provide the range of the input? For example, for the following code
#include <iostream>
#include <algorithm>
#include <vector>
int main()
{
std::vector<int> a = {4, 2, 1, 7};
std::vector<int> b = {1, 2};
std::copy(a.begin(), a.end(), b.begin());
for(auto val : b)
std::cout << val << std::endl;
}
with the output:
4
2
I don't understand how the algorithm knows that the capacity of the output container b is 2. I would have expected it assumes just the same range as the input container and therefore generates some kind of segmentation fault.
The
copyalgorithm doesn't check the iterator range, your program hasheap-buffer-overflowissues.The implementation for
copyis straightforward, just a simple loop, you can view libcxx's implementation here.It's a general memory issue, thanks to the great memory sanitizer tool in the compiler, we can quickly locate the problem. Though your program doesn't crash with SEGSEV now, it does have memory buffer overflow,if this is a large program, it is likely to cause other code to crash(maybe in a different thread, different library), and it is difficult to troubleshoot the cause since the crash code is just a victim.
Build with
-fsanitize=address, then we get a clear report after running the program:Memory sanitizer is a general memory tool. When focusing on the STL iterator debugging, the STL libraries do have some helpful utils:
For Visual Studio 2019, add
#define _ITERATOR_DEBUG_LEVEL 1into your code, or add it in the project configuration. We get exception when run your code, the call stack:We can see that an extra check function
_Verify_offsetis called, then the error is caught.For libstdc++ from gcc, there is also similar debugging mode.: compiler flag -D_GLIBCXX_DEBUG
Build your code with
compiler flag -D_GLIBCXX_DEBUGunder GCC 9 and run it, we get an error report:Which is helpful too!
For libcxx from LLVM, there are also something similar. But the document is somewhat not complete, you can give it a try.
Be careful that all the tools have performance degressions, so it's only useful in the test build and not suitable for a production build.