gpt4 book ai didi

c++ - 在 gdb 中打印 C++ std::set 字符串的第一个元素?

转载 作者:行者123 更新时间:2023-12-01 15:02:31 28 4
gpt4 key购买 nike

Element at index in a std::set?解释说,在 std::set 中没有索引的“直接”随机访问。 - 所以,我在这里尝试使用它的 .begin()返回迭代器的方法......这是一个简单的最小示例:

// g++ --std=c++11 -g test.cpp -o test.exe

#include <iostream>
#include <set>

int main()
{
std::set<std::string> my_set;
my_set.insert("AA");
my_set.insert("BB");
std::cout << "Hello World!" << std::endl;
return 0;
}

我最终想要做的是使用 gdb dprintf在我的实际问题中输入 break - 我不想更改代码,因此不添加额外的迭代器变量。自 dprintf使用格式说明符,其中 %s对于 C 风格的字符串,我最终需要的不仅仅是对 my_set 的第一个元素的引用,但我还需要调用 .c_str()在它上面 - 所有这些都在一个单行中。 (在我的实际问题中,我有一个自定义 String 类的 std::set,它有一个用于获取 C 样式字符串的自定义方法)。

问题是,我找不到访问第一个元素的正确语法:
$ gdb --args ./test.exe
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
...
Reading symbols from ./test.exe...done.
(gdb) b test.cpp:11
Breakpoint 1 at 0x8048bf8: file test.cpp, line 11.
(gdb) r
Starting program: /tmp/test.exe

Breakpoint 1, main () at test.cpp:11
11 std::cout << "Hello World!" << std::endl;
(gdb) p my_set
$1 = std::set with 2 elements = {[0] = "AA", [1] = "BB"}
(gdb) p my_set.begin()
Cannot evaluate function -- may be inlined
(gdb) p my_set->begin()
Cannot resolve method std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::begin to any overloaded instance
(gdb) printf "%s", my_set.begin()
Cannot evaluate function -- may be inlined

是否可以打印 std::set 的第一个值?在这样的上下文中使用 gdbprintf ,而无需更改代码(例如,添加迭代器变量)?

最佳答案

好吧,感谢@AndreyStarodubtsev 和@Amadeus 的评论,我到了某个地方。

一方面,正如@Amadeus 指出的那样 - 事实证明,您确实必须对程序中的某个类型进行某种引用,否则它可能会被优化掉。所以 OP 示例,实际上,在调试时会给出:

(gdb) p ((std::string*)(my_set._M_t._M_impl._M_header._M_left+1))->c_str()
A syntax error in expression, near `)(my_set._M_t._M_impl._M_header._M_left+1))->c_str()'.
(gdb) p std::string
No symbol "string" in namespace "std".

...然而,只是一个变量引用似乎足以解决这个问题:
// g++ --std=c++11 -g test.cpp -o test.exe

#include <iostream>
#include <set>

std::string aa; // just to have reference to std::string

int main()
{
std::set<std::string> my_set;
my_set.insert("AA");
my_set.insert("BB");
std::cout << "Hello World!" << std::endl;
return 0;
}

...虽然这是代码更改,但我不必添加引用内部迭代器的新实际代码行。然后,一个 gdb session 看起来像这样:
$ gdb --args ./test.exe
...
Reading symbols from ./test.exe...done.
(gdb) b 13
Breakpoint 1 at 0x8048c38: file test.cpp, line 13.
(gdb) r
Starting program: /tmp/test.exe

Breakpoint 1, main () at test.cpp:13
13 std::cout << "Hello World!" << std::endl;
(gdb) p ((std::string*)(my_set._M_t._M_impl._M_header._M_left+1))->c_str()
$1 = 0x804d014 "AA"
(gdb) printf "'%s'\n", ((std::string*)(my_set._M_t._M_impl._M_header._M_left+1))->c_str()
'AA'

以及访问 my_set 第一个节点的语法(这显然是节点的“红黑树”),我咨询了 https://gist.github.com/skyscribe/3978082 gdb @AndreyStarodubtsev 记录的脚本,特别是函数 pset (出于某种原因,这往往会给我带来语法错误——可能是因为优化了对 std::string 的引用)

关于c++ - 在 gdb 中打印 C++ std::set 字符串的第一个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33741879/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com