为什么调试器在if语句后开始任意跳转?

Why does debugger start to jump arbitrary after if-statement?

提问人:ArdaSenyurek 提问时间:11/6/2023 最后编辑:lemArdaSenyurek 更新时间:11/7/2023 访问量:123

问:

调试此功能时出现我的问题。

std::vector<patch_bundle> clean_up(std::vector<patch_bundle> vc){
    
    cout << "girdim ha";    
        for(auto itr = vc.begin(); itr != vc.end();){
    
            patch_bundle cmp_patch_bundle = *itr;
        string cmp_indices = cmp_patch_bundle.patch1_name;
        for(auto i_itr = vc.begin(); i_itr != vc.end();){
            if(i_itr != itr){
                patch_bundle tmp_patch_bundle = *i_itr; 
                string indices1 = tmp_patch_bundle.patch1_name;
                string indices2 = tmp_patch_bundle.patch2_name;
                if((indices1 == cmp_indices) || (indices2 == cmp_indices)){

                    vc.erase(i_itr);
                 }
                else{
                   ++i_itr;
                 }

               
             }
            else{
               ++i_itr;
             }
            
         }
        ++itr;
        
    }
 }

patch_bundle具体如下:struct

struct patch_bundle{
    int patch1[4] = {0,0,0,0};
    int patch2[4] = {0,0,0,0};
    std::string patch1_name;
    std::string patch2_name;

    std::string patch1_label;
    std::string patch2_label;

 };

下面是调试器输出:

Thread 1 hit Breakpoint 1, clean_up (vc=std::vector of length 5400, capacity 5400 = {...}) at test.cpp:338
338             cout << "girdim ha";
(gdb) n
girdim ha339                    for(auto itr = vc.begin(); itr != vc.end();){
(gdb)
341                     patch_bundle cmp_patch_bundle = *itr;
(gdb)
342                     string cmp_indices = cmp_patch_bundle.patch1_name;
(gdb)
343                     for(auto i_itr = vc.begin(); i_itr != vc.end();){
(gdb)
344                             if(i_itr != itr){
(gdb)
359                                ++i_itr;
(gdb)
343                     for(auto i_itr = vc.begin(); i_itr != vc.end();){
(gdb)
344                             if(i_itr != itr){
(gdb)
345                                     patch_bundle tmp_patch_bundle = *i_itr;
(gdb)
346                                     string indices1 = tmp_patch_bundle.patch1_name;
(gdb)
347                                     string indices2 = tmp_patch_bundle.patch2_name;
(gdb)
**348                                     if((indices1 == cmp_indices) || (indices2 == cmp_indices)){
**(gdb)
353                                        ++i_itr;
(gdb)
347                                     string indices2 = tmp_patch_bundle.patch2_name;
(gdb) n
346                                     string indices1 = tmp_patch_bundle.patch1_name;
(gdb)
345                                     patch_bundle tmp_patch_bundle = *i_itr;
(gdb)
344                             if(i_itr != itr){
(gdb)
345                                     patch_bundle tmp_patch_bundle = *i_itr;
(gdb)
346                                     string indices1 = tmp_patch_bundle.patch1_name;
(gdb)

然后在粗体线下方,先读出 而不是 。这似乎很奇怪。可能是什么原因?indices2indices1

值得注意的是,我最初只使用标准类型的迭代。问题发生在同一行粗体之后。所以我的猜测是,在记忆方面有些事情不太对劲。但它会影响他的行为吗?for(int itr = 0; ..;...)gdb

如果需要,我正在寻找更多信息。

谢谢。

C++ 调试 GDB

评论

1赞 PaulMcKenzie 11/6/2023
题外话(也许),但您是否知道这是在处理向量的副本,而不是您传入的向量?我看到很多事情正在发生,它给人的印象是你希望传入的向量被改变(当它不会改变时)。std::vector<patch_bundle> clean_up(std::vector<patch_bundle> vc)vcvc
2赞 Peter 11/6/2023
除了内存“不太正确”之外,如果你的代码是用优化(可以重新组织完成事情的顺序)或没有调试信息(这会影响调试器跟踪到达哪一行代码的能力)来编译的,那么你看到的行为类型是相当常见(而且有些正常)。
0赞 PaulMcKenzie 11/6/2023
可能是什么原因?-- 尽管此答案更特定于 Visual C++,但如果在启用优化的情况下编译代码,调试器也会发生相同的问题

答:

2赞 j6t 11/6/2023 #1

当您观察到 GDB 步入以下行时:

353                                        ++i_itr;
(gdb)
347                                     string indices2 = tmp_patch_bundle.patch2_name;
(gdb) n
346                                     string indices1 = tmp_patch_bundle.patch1_name;

您会看到它执行 的析构函数。std::string

0赞 ks1322 11/7/2023 #2

您可能 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88742 遇到此 GCC 错误。我假设您正在使用 GCC 进行编译。解决方案可以是将 GCC 更新到更新版本或使用 Clang。从错误描述来看,已知 GCC 在 10.5.0、5.5.0、6.4.0、7.3.0、8.2.0、9.0 版本上失败,已知在 11.0、4.7.4、4.8.5、4.9.4 版本上工作。