【问题标题】:segmentation fault while using custom sorting function to sort strings in a vector<string>使用自定义排序函数对向量中的字符串进行排序时出现分段错误<string>
【发布时间】:2015-10-01 13:04:18
【问题描述】:

我正在尝试对包含字符串的向量进行排序。我有以下主要功能的代码

int size;
cin >> size;
vector<string> s;
cout << "READ" << endl;
for (int i = 0; i<size; i++)
{
    string str;
    cin >> str;
    s.push_back(str);
}
cout << "READ" << endl;

cout << "Passed" << endl;
sort(s.begin(), s.end(), comp);

for (int i = 0; i<size; i++)
{
    string st = s.at(I);
    cout << st << endl;
}


return 0;

而comp函数代码为

bool comp(string s1, string s2)
{
    if (s1.empty() or s2.empty())
        return false;

    int l = s1.length();
    for (int i = 0; i<l; i++)
    {
        if (s1[i] > s2[i])
            return true;
    }
    return false;
}

但是对于这个输入,我遇到了分段错误

46
lnpxeemwlqlzpxrmrmwbseqfnpkzaafdnukixaopcfvhqw
dhfhhoyhhzleldljmirjbqagcleivzomlpanqzsmqnrzij
zcsrvgqlmrgknqhwtcqzyldjanlczysnspvusziqtazjlu
idiknfqdygrwhvdzperlvgueqhuezsrwzztlodqgipnqzb
zjfyxbghvdecpzhvoxzojcpciaspyoeaetimmoccjqxtmv
mxwnhdyjutecwbrxdjmrbdjvbzprgnekvnvhxnuvekoflo
jjbjxzuaafatzdwlnzcorkiagrwzvrmjqqbdlmgyewzsea
bmvyqojhnbfrypiiwvtgifmqqdcuilohbfvkqjhlcwsfyo
zrbjhsrxnllmsdfqurkjfomwsvgfepwttohojxmrhexpmy
hcdxtucpeptgqhckpdxdcgpvhkiuucvwbuhtmbskqdlasw
rtocxkyrsrbluwvpfkekqkdwncvozfgmcrswpksiqmfnnl
xawlpinqjstxvrqvsugbvszhibbcmbdwktgwjlezakyqrr
cfghwolkahdafrcuufklziipmtkhuxdrxqlavcrxavxuas
plcsutiemkgfunhpyeiuvxwjppzsopglcyhgidsyhjnutp
vyyrbmfyfwpcowlpytmkvsyrzgiausrulsxtwysjgpgtqi
bsoknggdytplubxzjczatotnpovriwibeamjfnyxibvama
imkshtavbjpnkafuxwbzpiqlnnotrxmjepzeuwtuewtqab
ttjzqrcdcofkljaevmauexsxlkrxuanxgrsmsrxckixpoz
aocndkatjggduuyiksgmovthyoomrfsaxlnjouszxxoqtc
ahmkgizkvsbrqyricbtnpvpnibvgvnnrnqphkstvcjsbli
biasqbcofwdgabnipodjkriiyqlhaddpegkmydutcyoksk
avyaodwtgbdsnhheoearlinfcadeteiiudobbvqdqizcry
mhdekyvubghealrenyshjcjuhxxzimsgvukcdfdbjramzq
ayrzjanrebdgowsngullkgyvlgqzjexebleigxvgwjnbyf
vcpnclkhoawabjlhfnrncxfswjjmpxqcwoeqpyaitwdrjf
ghngenuvshwuaubahlzazwmgnsmtzyqfvvoxnhiufhxpac
ljrwslmgjilvdommuvpebcznjalxuazyujtzpewdbxjnwj
jqirnjnheowbioheyleyhkrcyfxuweyipumfojetmvomuz
vnnlsozyplofqkxfwcmlyntfrhspvbscocodlejqrymdeu
lgjcimksyragrhhagkmlnaysfxzswxfkhqzrhjlgkemmhp
weoxhopddcyiiikwblqvvcxcuxkebhywdacpmjrlkosxmw
bwcxxsytqdpybjxyqgmggitkgpkiytnwprsnxrygryxigo
qtwyleqxqflmaudekmdmgscfvjfwkchacxmokxrcfgwnhl
dgcmvhgnzigmrxougsbhwdhugyvloaqlliybbzkttmolln
jqmrfoyhwxbiyvzntvxozfswwjbeybahggfjrrzzhbapyi
oxbjadgrttqnfbevqolflhdpmgwgudhwfeebauqhhygvnt
kwmqirrljycddqcvjanibiarpcjjqiuvkdbdyzogbcixah
yyykebcfsnixcjdbkxtqvqynafmtuvoepeayiaqinvmjen
lsyxwgpfxlfkxckzsjzonxkhullkatmnwwfuicgjzbnvzf
vihglfapunknuitwtcxzdwjyfwqurvsydacylgcyohrbou
olmojrovoqseuqausssdupqzhbmyblomlbbqzwgbtgyiwq
tcshhbdgxsrtxywgqahqfimbnckwdhtbzlpwevuqjyqrbd
vjmcknagopzpwrmrianbgyhyginqduwdfjgmdqttcqroof
srmfsjigydlqlgsmvgqddpqmqkjzptzwdfpjmpnvgaezlx
yphbhtrmqcnrfklqmkblvginnhxxtlnnwcfuwujdqwkvaq
jahvrihhicrqvttmdzwbemjjqnstvtudvifdvrbjxalirj

对于很多其他输入,它给出了正确的结果,但对于上述结果,我得到了这个结果

READ
READ
Passed

我搜索了很多,但在我的 comp 函数中找不到错误。

【问题讨论】:

  • 你为什么不只使用std::greater
  • 其实我不知道...我一定会试试的
  • 问题是你在比较函数中没有使用s2的长度
  • 输入的约束是每个字符串的长度必须相同
  • 然后添加一个验证长度相同的测试。否则,输入中的错误将导致未处理的错误。

标签: c++ sorting stl stdvector


【解决方案1】:

正如其他人所指出的,您的比较功能已/已损坏。

这是一个使用std::greater&lt;std::string&gt;() 作为比较函数的示例:

#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
#include <vector>

int main() {
    int size;
    if (!(std::cin >> size)) return -1;

    std::vector<std::string> v;
    for (int i = 0; i < size; i++) {
        std::string str;
        if (!(std::cin >> str)) return -1;
        v.push_back(str);
    }

    std::sort(v.begin(), v.end(), std::greater<std::string>());

    for (int i = 0; i < v.size(); i++) {
        std::cout << v[i] << std::endl;
    }

    return 0;
}

输出按降序排序(test.txt 包含上述输入):

$ g++ test.cc && ./a.out < test.txt
zrbjhsrxnllmsdfqurkjfomwsvgfepwttohojxmrhexpmy
zjfyxbghvdecpzhvoxzojcpciaspyoeaetimmoccjqxtmv
zcsrvgqlmrgknqhwtcqzyldjanlczysnspvusziqtazjlu
yyykebcfsnixcjdbkxtqvqynafmtuvoepeayiaqinvmjen
yphbhtrmqcnrfklqmkblvginnhxxtlnnwcfuwujdqwkvaq
xawlpinqjstxvrqvsugbvszhibbcmbdwktgwjlezakyqrr
weoxhopddcyiiikwblqvvcxcuxkebhywdacpmjrlkosxmw
vyyrbmfyfwpcowlpytmkvsyrzgiausrulsxtwysjgpgtqi
vnnlsozyplofqkxfwcmlyntfrhspvbscocodlejqrymdeu
vjmcknagopzpwrmrianbgyhyginqduwdfjgmdqttcqroof
vihglfapunknuitwtcxzdwjyfwqurvsydacylgcyohrbou
vcpnclkhoawabjlhfnrncxfswjjmpxqcwoeqpyaitwdrjf
ttjzqrcdcofkljaevmauexsxlkrxuanxgrsmsrxckixpoz
tcshhbdgxsrtxywgqahqfimbnckwdhtbzlpwevuqjyqrbd
srmfsjigydlqlgsmvgqddpqmqkjzptzwdfpjmpnvgaezlx
rtocxkyrsrbluwvpfkekqkdwncvozfgmcrswpksiqmfnnl
qtwyleqxqflmaudekmdmgscfvjfwkchacxmokxrcfgwnhl
plcsutiemkgfunhpyeiuvxwjppzsopglcyhgidsyhjnutp
oxbjadgrttqnfbevqolflhdpmgwgudhwfeebauqhhygvnt
olmojrovoqseuqausssdupqzhbmyblomlbbqzwgbtgyiwq
mxwnhdyjutecwbrxdjmrbdjvbzprgnekvnvhxnuvekoflo
mhdekyvubghealrenyshjcjuhxxzimsgvukcdfdbjramzq
lsyxwgpfxlfkxckzsjzonxkhullkatmnwwfuicgjzbnvzf
lnpxeemwlqlzpxrmrmwbseqfnpkzaafdnukixaopcfvhqw
ljrwslmgjilvdommuvpebcznjalxuazyujtzpewdbxjnwj
lgjcimksyragrhhagkmlnaysfxzswxfkhqzrhjlgkemmhp
kwmqirrljycddqcvjanibiarpcjjqiuvkdbdyzogbcixah
jqmrfoyhwxbiyvzntvxozfswwjbeybahggfjrrzzhbapyi
jqirnjnheowbioheyleyhkrcyfxuweyipumfojetmvomuz
jjbjxzuaafatzdwlnzcorkiagrwzvrmjqqbdlmgyewzsea
jahvrihhicrqvttmdzwbemjjqnstvtudvifdvrbjxalirj
imkshtavbjpnkafuxwbzpiqlnnotrxmjepzeuwtuewtqab
idiknfqdygrwhvdzperlvgueqhuezsrwzztlodqgipnqzb
hcdxtucpeptgqhckpdxdcgpvhkiuucvwbuhtmbskqdlasw
ghngenuvshwuaubahlzazwmgnsmtzyqfvvoxnhiufhxpac
dhfhhoyhhzleldljmirjbqagcleivzomlpanqzsmqnrzij
dgcmvhgnzigmrxougsbhwdhugyvloaqlliybbzkttmolln
cfghwolkahdafrcuufklziipmtkhuxdrxqlavcrxavxuas
bwcxxsytqdpybjxyqgmggitkgpkiytnwprsnxrygryxigo
bsoknggdytplubxzjczatotnpovriwibeamjfnyxibvama
bmvyqojhnbfrypiiwvtgifmqqdcuilohbfvkqjhlcwsfyo
biasqbcofwdgabnipodjkriiyqlhaddpegkmydutcyoksk
ayrzjanrebdgowsngullkgyvlgqzjexebleigxvgwjnbyf
avyaodwtgbdsnhheoearlinfcadeteiiudobbvqdqizcry
aocndkatjggduuyiksgmovthyoomrfsaxlnjouszxxoqtc
ahmkgizkvsbrqyricbtnpvpnibvgvnnrnqphkstvcjsbli

供参考:

【讨论】:

  • 是的,使用std::greater 是最好的方法...感谢您提供的信息
【解决方案2】:

你的 comp 方法坏了。

对于这两个字符串“ac”和“ca”,comp("ac", "ca")comp("ac", "ca") 一样为真。因为你在s1[i] &lt; s2[i]尝试下一个位置的时候应该马上返回false。

正如你在 cmets 中所说,你应该通过使用较短的长度来处理不同长度的字符串,以避免访问过去的字符串长度时出错。

所以你的comp方法应该是:

bool comp(string s1,string s2)
{
    // empty string comes last
    if(s1.empty()) return false;
    if(s2.empty()) return true;

    // limit to shorter string length
    unsigned int l = s1.length();
    if (s2.length() < l) l = s2.length();
    for(unsigned int i=0;i<l;i++)
    {
        // if chars are different at position i return immediately
        if(s1[i] > s2[i])
            return true;        
        if(s1[i] < s2[i])
            return false;        
    }
    // shorter string comes last
    return(s1.length() >= s2.length());
}

【讨论】:

  • 不,两个字符串的长度必须相同...这是一个约束
  • 并且还有一个约束,如果上面的字符串有一个大于两个字符串下面字符串中对应索引处的字符的字符应该交换
【解决方案3】:

这个条件:

 if (s1.empty() or s2.empty())
    return false;

不满足comp函数的严格弱排序要求(来自https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings

如果 x

在您的情况下,如果 z 是空字符串,而 xy 不是,则它既不满足 x &lt; z 也不满足 z &lt; y

可能的实现是:

if( s2.empty() ) return !s1.empty();
if( s1.empty() ) return false;

但我不明白为什么不能使用 std::greater std::string::comparestd::string::operator&gt;() 而不是手动实现

【讨论】:

  • 如果你能给出更新的代码那就太好了......然后我可以清除我的严格弱排序的概念
  • 你能不能给我完整的comp函数代码,它不会因上述输入而受到分段错误的影响......这会很棒......
猜你喜欢
  • 2017-02-06
  • 2021-08-03
  • 1970-01-01
  • 2013-05-08
  • 1970-01-01
  • 2017-05-03
  • 1970-01-01
  • 2016-12-03
  • 1970-01-01
相关资源
最近更新 更多