Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ sort vector of pointers error

I have a vector vec that I need to sort every time I put an element inside it

so when I put the first Upgrade* inside the vector I have no problems

but when I put the second Upgrade* inside it and the sort routine is called I have a runtime error

this is how I put elements and call sort every time I insert

std::vector<Upgrade*> stack = getStack();

stack.push_back(element);

std::sort(stack.begin(), stack.end(), CostBenefitUpgradeOrder());

and this is my comparator

struct CostBenefitUpgradeOrder {
    bool operator ()(const Upgrade * u1, const Upgrade * u2) const {

        const UpgradeType upgradeType1 = u1->getUpgradeType();
        const UpgradeType upgradeType2 = u2->getUpgradeType();

        int price1 = PriceUtil::getPrice(upgradeType1);
        int price2 = PriceUtil::getPrice(upgradeType2);

        if (price2 < price1)
            return true;
        else
            return false;
    }
}

and this is the error

runtime error

I have noticed that it only happens when I execute the program in Debug mode!!

like image 348
thiagoh Avatar asked May 19 '26 19:05

thiagoh


2 Answers

Your comparison function is broken. You cannot have a predicate that returns true for both u1 < u2 and u2 < u1.

Replace the return statement with return u1 < u2; if you just need something for a quick test.

Also, are you sure you need to use a vector? Unless you need the pointers to be stored in contiguous memory, you'd be better off using an std::set instead with an appropriate comparator. The set will keep the elements ordered after every insertion / deletion.

Also, since you're using raw pointers, if you're allocating the objects using new make sure you delete before removing elements from the container. Better yet, use an std::set<std::unique_ptr<Upgrade>, CostBenefitUpgradeOrder> instead and not have to worry about deleting the allocated memory.

like image 199
Praetorian Avatar answered May 22 '26 08:05

Praetorian


You need to pass "strict weak ordering" (less than) operator to the std::sort method, and that operator must be "valid".

Valid operator< have the following properties:

  • For all x, it is not the case that x < x (irreflexivity). For all x,
  • y, if x < y then it is not the case that y < x (asymmetric). For all
  • x, y, and z, if x < y and y < z then x < z (transitivity). For all x,
  • y, and z, if x is incomparable with y, and y is incomparable with z, then x is incomparable with z (transitivity of incomparability).

You can see that your operator fails on the first point (CostBenefitUpgradeOrder(x, x) == true, in your case) (and on most other points, as well).

like image 36
Nemanja Boric Avatar answered May 22 '26 07:05

Nemanja Boric



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!