简体   繁体   中英

segmentation fault while using custom sorting function to sort strings in a vector<string>

I am trying to sort a vector that contains strings. I have the following code for the main function

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;

And the comp function code is

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;
}

But for this input I am getting a segmentation fault

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

For a lot other inputs it gives correct result but for the above result I get this result

READ
READ
Passed

I have searched a lot but cannot find the error in my comp function.

Your comp method is broken.

For those two strings "ac" and "ca", comp("ac", "ca") is true as is comp("ac", "ca") . Because you try next position when s1[i] < s2[i] when you should return immediately false.

And as you were said in comments, you should cope with strings of different length by use the length of the shorter to avoid errors for accessing past string length.

So you comp method should be:

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());
}

As the others have noted, your comparison function is/was broken.

Here's an example that uses std::greater<std::string>() as a comparison function:

#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;
}

The output is sorted in descending order (test.txt containing above input):

$ 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

For reference:

This condition:

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

does not satisfy strict weak ordering requirement to comp function (from https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings )

If x < y, then for all z, either x < z or z < y or both.

In your case if z is empty string and x and y are not, it would not satisfy either x < z nor z < y

Possible implementation is:

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

But I do not see why you cannot use either std::greater std::string::compare or std::string::operator>() instead of manual implementation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM