I am debugging some C++ code and I have a really large std::vector<floating_point_type>
(float
or double
). In C++ code when I want the max value of the std::vector
I can just use std::max_element()
. So in gdb
I tried to use the same code, but I got an error.
In gdb
I used call std::max_element(x)
and got an error message No symbol "max_element" in namespace "std".
Is there any way to get the max value of a vector in gdb
?
I would also appreciate an explanation for why my attempt at using std::max_element
was not working (perhaps std::max_element
a header-only or inline function).
You can use max_element to get the maximum value in vector. The max_element returns an iterator to largest value in the range, or last if the range is empty. As an iterator is like pointers (or you can say pointer is a form of iterator), you can use a * before it to get the value.
The max() function in C++ accepts two values and returns the larger one. This function is available in <algorithm. h> . The max() function helps during coding contests when you want to find the maximum of two values in the logic.
The usual way to examine data in your program is with the print command (abbreviated p ), or its synonym inspect . It evaluates and prints the value of an expression of the language your program is written in (see section Using GDB with Different Languages).
std::max_element
is a function template, not a function. You are asking GDB to do template argument deduction and the whole shebang involved with calling a template function without specifying arguments. It can't do that, naturally, it's not a full fledged compiler.
As far as I know any solution, from the simplest to the most complex, will require of you to modify your source in such a way that std::max_element
is instantiated for the iterator types of your vector. So you may as well add "debug only" code that computes the maximum element and stores it into a local variable.
(gdb) p std::max⭾⭾⭾
(No response from gdb)
(gdb) p std::max_element(v.begin(), v.end())
No symbol "max_element" in namespace "std".
Here is how to call an uninstantiated function template from gdb
without breaking your session and recompiling your program.
Open an editor and create a C++ source file with an explicit instantiation of the needed function. For example:
// /tmp/tmpsource.cpp
#include <algorithm>
#include <vector>
using T = std::vector<int>::iterator;
template T std::max_element<T>(T, T);
This can probably be automated somehow with a shell script. Give it a name of a function and template arguments, and it will generate you a complete buildable C++ source. Probably not worth the trouble though.
Build a shared library/DLL from the source.
g++ -fPIC -shared -ggdb -O0 -o /tmp/libtmpsource.so /tmp/tmpsource.cpp
Load the library in your debugging session.
load /tmp/libtmpsource.so
# if this doesn't work
p dlopen("/tmp/libtmpsource.so", 2)
# or perhaps even
p LoadLibraryA("c:/temp/libtmpsource.so")
Let's try the function now.
(gdb) p std::max_element(v.begin(), v.end())
No symbol "max_element" in namespace "std".
What? No worries, everything is under control. gdb is not a C++ compiler and it cannot do the template deduction thing. You need to specify your <...>
yourself. Fortunately, autocompletion works (sometimes).
(gdb) p std::max⭾
(gdb) p std::max_element<__gnu_cxx::__normal_iterator<int*, std::vector<int,
std::allocator<int> > > >(__gnu_cxx::__normal_iterator<int*, std::vector<int,
std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int,
std::allocator<int> > >)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With