Accessing vector items in GDB
Asked Answered
A

3

5

For example, I have such struct in a templated class:

struct Foo{
    int data;
    vector<Foo*> children;
}

And to print out the data value, I can simply do this: (let bar be a pointer to a Foo)

print bar->data

and this works fine. However I would like to also follow children to another Foo. I tried:

print bar->children[0]->data

but it doesn't work. How should I access the items in a vector and use it in print?

Ammoniacal answered 12/4, 2015 at 8:16 Comment(0)
A
3

With help from this answer, explicitly instantiating the vector fixes the problem.

For example,

template class std::vector<double>;
Ammoniacal answered 28/6, 2015 at 19:50 Comment(4)
Can you give an example showing how it solved your problem?Retrospect
@user Sure, I’ve included the snippet from the linked answer.Vanhoose
How would I use it in gdb? I would run: gdb) template class std::vector<double>; and them gdb) print bar->data ?Retrospect
IIRC I had to place it in the source code.Vanhoose
S
5

With GDB 7.9 and g++ 4.9.2, it works quite well while printing bar->children[0]->data.

But, here is also an indirect method to access these elements: print (*(bar->children._M_impl._M_start)@bar->children.size())[0]->data where VECTOR._M_impl._M_start is the internal array of VECTOR and [email protected]() is used for limiting the size of a pointer.

reference: How do I print the elements of a C++ vector in GDB?

Complement:

There is also another not so elegant but more general way:

print bar->children[0]

and you might get something like this:

(__gnu_cxx::__alloc_traits<std::allocator<Foo*> >::value_type &) @0x603118: 0x603090

so you can access to it with the pointer given above: print ((Foo)*0x603090).data

Sirkin answered 12/4, 2015 at 8:41 Comment(6)
I'm getting an error saying There is no member or method named _M_impl. Probably that's because I'm using clang++ instead of g++.Vanhoose
So can I know your environment? Because accessing to internal array of vector depends closely on implementationof compilers...Sirkin
Clang++, libc++, C++14 with no optimization.Vanhoose
What's the output of print bar->children[0]? If you can get the pointer of this element, then you can print data field with "print ((Foo)*ADDRESS).data"Sirkin
When I try to do bar->children[0] it just says Could not find operator[].Vanhoose
Oh I just found another solution that made it worked by explicitly instantiating the vector. Thanks anyway.Vanhoose
A
3

With help from this answer, explicitly instantiating the vector fixes the problem.

For example,

template class std::vector<double>;
Ammoniacal answered 28/6, 2015 at 19:50 Comment(4)
Can you give an example showing how it solved your problem?Retrospect
@user Sure, I’ve included the snippet from the linked answer.Vanhoose
How would I use it in gdb? I would run: gdb) template class std::vector<double>; and them gdb) print bar->data ?Retrospect
IIRC I had to place it in the source code.Vanhoose
C
0
template <> Foo* &std::vector<Foo*>::operator[](size_type n) noexcept
{
    return this->begin()[n];
}

to use vector operator[], need the Template materialization

Contravene answered 1/5, 2022 at 2:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.