📅 2015-Feb-10 ⬩ ✍️ Ashwin Nanjappa ⬩ 🏷️ container, cpp, debug mode, vector ⬩ 📚 Archive
The containers of the C++ standard library are incredibly useful to write compact code without having to reinvent basic data structures. Since the focus of C++ is always on performance, error checking is not performed in the use of these containers. For example, in a std::vector
with 35
elements, you can access v[39]
without C++ blinking an eye. You will of course get back invalid data that might silently poison the runtime execution of the program. std::vector
offers a safer at(39)
method that does the bounds checking, but it is slower and so not all code will use it. When a strange runtime error does occur in code using C++ containers, how to debug it?
If you are using GCC, thankfully it provides an alternate debug mode version of the C++ standard library where all the calls perform error checking. Finding your error becomes easier by using these debug mode C++ standard library containers.
You can change your entire C++ code to link with the debug C++ standard library by adding the -D_GLIBCXX_DEBUG
compiler flag. This will replace all use of C++ standard library containers to their debug versions. On running the program, the container should report any error it finds.
However, this option may not be feasible if you are passing any C++ container in calls to external libraries (say OpenCV). Since these external libraries may not have been compiled with these flag, they cannot be linked. You will have to recompile all these external libraries with this flag to be able to link with them.
For example, my C++ code was calling some functions in OpenCV and passing a std::vector
. On compiling with this debug flag, I got this error:
main.cpp.o: In function `main':
main.cpp:92: undefined reference to `cv::imwrite(std::string const&, cv::_InputArray const&, std::__debug::vector<int, std::allocator > const&)'
error: ld returned 1 exit status
The error is indicating that it cannot find a OpenCV function definition that takes a std::__debug::vector
as input.
If you are stuck with the above scenario where you use an external library that is not compiled in this debug mode, there is an alternative. Find the definitions of containers in your code that are suspect and only change those specifically to the debug version of the container.
For example, I suspected a certain std::vector
in my code, so I changed its definition to:
#include <debug/vector>
// Earlier this was:
// std::vector<int> pick_vec;
// Changed now to:
std::__gnu_debug::vector<int> pick_vec;
On compiling and running this code, the out-of-bounds error was found by the debug container:
/usr/include/c++/4.9/debug/vector:357:error: attempt to subscript container
with out-of-bounds index 39, but container only holds 35 elements.
Objects involved in the operation:
sequence "this" @ 0x0x7ffffc4d5fe0 {
type = NSt7__debug6vectorIN2cv7Point3_IfEESaIS3_EEE;
}
The list of C++ debug containers and their header files can be found listed here.
Tried with: GCC 4.9 and Ubuntu 14.04