首页 > 解决方案 > 使用比较器排序时的未定义行为

问题描述

我需要从字符串中解析数字,并在第一个数字的升序范围内对向量进行排序,如果第一个数字等于,则按字母顺序排列第二个数字,如字符串: [1, 250; 2, 30; 4, 40; 1, 26]-> [1, 250; 1, 26; 2, 30; 4, 40]
由于“250”<“26”,数组像以前一样排序。

有算法:

#include<assert.h>
#include<vector>
#include<string>

int sum_digits(int a);

string orderWeight()
{
    vector<pair<int, int> > weight_number;
    string str = "103 123 4444 99 2000 ";
    string Numbers = "1234567890";
    int Num;
    for (auto i_beg = str.cbegin(); i_beg < str.cend(); ++i_beg)
    {
        if (Numbers.find(*i_beg) != string::npos)
            for (auto i_end = i_beg + 1; i_end < str.cend(); ++i_end)
            {
                if (Numbers.find(*i_end) == string::npos)
                {
                    Num = stoi(string(i_beg, i_end));
                    weight_number.emplace_back(sum_digits(Num)/*This function count sum of digits*/, Num);
                    i_beg = i_end;
                    break;
                }
            }
    }
    sort(weight_number.begin(), weight_number.end(),
       [](const pair<int, int>& a, const pair<int, int>& b) -> bool {
        if (a.first != b.first)
            return a.first < b.first;
        string s1 = to_string(a.second);
        string s2 = to_string(b.second);
        bool res = s1.compare(s2) < 0;
        return res;
    });

    string result;
    for (auto El: weight_number)
    {
        result += to_string(El.second) + " ";
    }
    result.pop_back();
    return result;
}

int sum_digits(int a)
{
    int sum = 0;
    for (; a > 0; a /= 10)
    {
        sum += a % 10;
    }
    return sum;
}

int main ()
{
assert(orderWeight()=="2000 103 123 4444 99")
return 0;
}

在 gcc 上一切正常,但是 clang 编译器抛出一个错误:

UndefinedBehaviorSanitizer:DEADLYSIGNAL
==1==ERROR: UndefinedBehaviorSanitizer: stack-overflow on address 0x7ffc35a59000 (pc 0x7f6029c2bb1f bp 0x000000001fff sp 0x7ffc35a562a8 T1)
==1==WARNING: invalid path to external symbolizer!
==1==WARNING: Failed to use and restart external symbolizer!
    #0 0x7f6029c2bb1e  (/lib/x86_64-linux-gnu/libc.so.6+0x18eb1e)
    #1 0x7f602a60a137  (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x13d137)
    #2 0x7f602a5f9432  (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x12c432)
    #3 0x42be9d  (/workspace/test+0x42be9d)
    #4 0x42b9a2  (/workspace/test+0x42b9a2)
    #5 0x425660  (/workspace/test+0x425660)
    #6 0x4258b7  (/workspace/test+0x4258b7)
    #7 0x42838c  (/workspace/test+0x42838c)
    #8 0x426a9e  (/workspace/test+0x426a9e)
    #9 0x426622  (/workspace/test+0x426622)
    #10 0x4261db  (/workspace/test+0x4261db)
    #11 0x42b5a5  (/workspace/test+0x42b5a5)
    #12 0x42573d  (/workspace/test+0x42573d)
    #13 0x7f6029abeb96  (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #14 0x404679  (/workspace/test+0x404679)

==1==ABORTING

如果我发表评论if(..),或者写res=true,或者s1="Something",或者s2 ="Something"没有to_string(.second)这个错误就会消失。但是该程序的工作原理与我需要的完全相反。我已经在搜索引擎中搜索没有任何结果。
我应该怎么做才能消除 clang 编译器上的这个错误?

标签: c++clang

解决方案


正如我在评论中所写的那样,也许网站www.codewars.com出错了,因为我也使用 clang 编译器尝试过它并且没有错误。
谢谢大家试图帮助我解决我的问题!


推荐阅读