Home > Blockchain >  Program crashes when using custom compartor for std::set
Program crashes when using custom compartor for std::set

Time:07-25

I tried to use custom comparator in a std::set. When I insert cuisine "japaneses" in a variable bucketCuisines, I get error DEADLYSIGNAL.

But, If i eliminate the custom comparator cmp there is no problem. But of course my results are incorrect.

Input:

["FoodRatings","highestRated","highestRated","changeRating","highestRated","changeRating","highestRated"]
[[["kimchi","miso","sushi","moussaka","ramen","bulgogi"],["korean","japanese","japanese","greek","japanese","korean"],[9,12,8,15,14,7]],["korean"],["japanese"],["sushi",16],["japanese"],["ramen",16],["japanese"]]

Result:

[null, "kimchi", "ramen", null, "sushi", null, "ramen"]
class FoodRatings {
public:
    static bool cmp(pair<int, string> a, pair<int, string> b){
        if(a.first == b.first)
            return a.second < b.second;
        return a.first > b.first;
    }
    
    unordered_map<string, int> bucketFoods;
    unordered_map<string, string> bucketFoodNCuisine;
    map<string, set<pair<int, string>, decltype(cmp)*>> bucketCuisines;
    
    FoodRatings(vector<string>& foods, vector<string>& cuisines, vector<int>& ratings) {
        int n = foods.size();
        for(int i=0; i<n; i  ){
            bucketFoods.insert(make_pair(foods[i],ratings[i]));
            cout << "1 ok\n";
            bucketFoodNCuisine.insert(make_pair(foods[i], cuisines[i]));
            cout << "2 ok\n";
            bucketCuisines[cuisines[i]].insert(make_pair(ratings[i], foods[i]));
            cout << "3 ok\n";
        }
    }
    
    void changeRating(string food, int newRating) {
        int oldRating = bucketFoods[food];
        bucketFoods[food] = newRating;
        string temp = bucketFoodNCuisine[food];
        bucketCuisines[temp].erase(bucketCuisines[temp].find(make_pair(oldRating, food)));
        bucketCuisines[temp].insert(make_pair(oldRating, food));
    }
    
    string highestRated(string cuisine) {
        return bucketCuisines[cuisine].begin()->second;
    }
};

CodePudding user response:

Your data type set<pair<int, string>, decltype(cmp)*> is an odd way to specify the comparator as a function pointer. But that's what it does, and the issue is likely because you never provide a valid comparator when constructing these sets.

When you add an entry to bucketCuisines, you're currently relying on the default constructor for this set. But that will initialize the comparator function pointer to nullptr. When you go to add stuff to the set, the null comparator is invoked and your program crashes.

The simplest way around this is to make the comparator a functor instead:

struct cmp {
    bool operator()(const pair<int, string>& a, const pair<int, string>& b) const
    {
        if(a.first == b.first)
            return a.second < b.second;
        return a.first > b.first;
    }
};

map<string, set<pair<int, string>, cmp>> bucketCuisines;
  • Related