3

Both problems are solved when I change "<=" to "<": it worked! I don't know why, can someone answer me? Thanks!!!

The first problem

code:

#include <bits/stdc++.h>
using namespace std;

int main(){
    string s[30];
    int n = 20;

    for(int i = 0; i < n; i++){
        s[i] = "3";
    }
    sort(s, s + n, [](string a, string b){
        return a <= b;
    });

    return 0;
}

error:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

The second problem

code:

#include <bits/stdc++.h>
using namespace std;

int main(){
    string s[30];
    int n = 20;

    for(int i = 0; i < n; i++){
        s[i] = "3";
    }
    sort(s, s + n, [](const string& a, const string& b){
        return a <= b;
    });

    return 0;
}

error:

Segmentation fault
Ralf Ulrich
  • 1,575
  • 9
  • 25
weiweiwei
  • 31
  • 5
  • 7
    That's the nature of [`std::sort`](https://en.cppreference.com/w/cpp/algorithm/sort), it *requires* a `less` relation, *not* a `less or equal`. You are violating this constraint, thus you run into undefined behaviour. – Aconcagua May 27 '21 at 08:48
  • 4
    Side note: https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h – Aconcagua May 27 '21 at 08:49
  • 3
    About [using namespace std](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). – Aconcagua May 27 '21 at 08:50
  • @Aconcagua Thanks ! I'll read it carefully – weiweiwei May 27 '21 at 09:03
  • Your THIRD problems, see [Why should I not #include ?](https://stackoverflow.com/q/31816095/3422102) – David C. Rankin May 28 '21 at 08:05
  • @DavidC.Rankin , thank you so much , I'm a beginner of C++, and I will read it carefully – weiweiwei May 29 '21 at 08:59

2 Answers2

1

You should use '<' for ascending sort, but you can use <=. The key is:

comparison function object (i.e. an object that satisfies the requirements of Compare) which returns ​true if the first argument is less than (i.e. is ordered before) the second.

std::sort

So <= will satisfy the requirement, (if and only if there are differences in all values being sorted) but it was not intended for that purpose and the = part is simply superfluous in the case all elements are different and likely undefined where all elements are the same. The < is evaluated and controls the sort. Don't use <= the sort compare function requires < or >. See C++ named requirements: Compare

Do not #include <bits/stdc++.h>. Use the proper headers that provide the prototypes and functionality necessary for your program. See also Why is “using namespace std;” considered bad practice?

Taking both into consideration and cleaning up the example a bit, you could do:

#include <iostream>
#include <string>
#include <algorithm>

#define MAXS 30         /* if you need a constant, #define one (or more) */

int main () {
    
    std::string s[MAXS] {};

    for(int i = 0; i < MAXS; i++) {         /* loop assigning to all strings */
        s[i] = std::to_string (i % 10);     /* convert (i % 10) to string */
    }
    /* sort the array of std::string */
    std::sort (s, s + MAXS, [](const std::string& a, const std::string& b){
                               return a < b; });
    
    for (const auto& st : s)                /* output results */
        std::cout << st << '\n';
}

Look things over and let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • If `<=` will work, then why does it not...? – underscore_d May 28 '21 at 08:35
  • In the original problem you have an array of std::string only partially initialized (the first 20 of 30 elements), the range of 20 is all filled with `"3"`. They are already in sort-order when `sort` is called so you wouldn't expect any change. There the `=` would cause nothing but meaningless swapping of elements that would never end -- because nothing ever changes. – David C. Rankin May 28 '21 at 08:41
  • The edit makes that much better, thanks. I have no idea why you are recommending a global `#define` though, when a local `const` or `constexpr` would work and not pollute the entire global namespace. It seems odd to give great advice on other common newbie gotchas to avoid, while then adding one of your own ;-) – underscore_d May 28 '21 at 09:26
  • `constexpr` is 100% fine -- old C programmer `:)` – David C. Rankin May 28 '21 at 18:00
  • `const` should also work fine in this case, long before `constexpr`. – underscore_d May 28 '21 at 18:11
  • Well, the technical effect of `#define`, `const` and `constexpr` are the same. The difference, as you point out, is one of scope. Depending on where the constant is required will determine if one is required or not. That's not something I would classify as a newbie gotcha. When global scope is needed, `#define` or `enum` provide the integer constants, neither a `const` qualified or `constexpr` can be initialized as a single global. If needed only within a single scope, then `const` or `constexpr` would be preferred. – David C. Rankin May 28 '21 at 18:23
  • Thank you so much! Now I'm understand it – weiweiwei May 29 '21 at 09:03
-3

You should review the logic of line 6 and the value in the for loop for two different data types, how can they add up to compare?

Thanh
  • 1
  • This is the key, why is there a problem if all elements are the same? Equal elements can also be compared – weiweiwei May 27 '21 at 09:06