0

getting heap use after free error in Leetcode, don't seem understand the root cause.Can you guys help me out here?

Mostly everything is declared on stack. My only suspect is the shallow copy I create on the stack multiset temp but you can't free anything on the stack right which is not created on heap?

class Solution {
public:

    void earn_points(multiset<int> points,int currpoint, int& max){

        set<int> unique;


        if(points.size() == 0){
             cout <<"finalscore="<< currpoint << " "<<endl;

            if(currpoint > max){
                max = currpoint;
            }
        }

        multiset<int> temp = points;

        for(auto it=points.begin(); it != points.end(); ++it){

            int num = *it;

            if(unique.find(num) != unique.end()){
                continue;
            }

            unique.insert(num);

            int delete_num1 =  num + 1;
            int delete_num2 =  num - 1;

            points.erase(it);

            if(points.find(delete_num1)  != points.end())
                 points.erase(delete_num1);

            if(points.find(delete_num2)  != points.end())
                    points.erase(delete_num2);

             cout << num <<"   ";

             for(auto i : points){
                 cout << i <<" ";
             }

             cout << endl;


             earn_points(points,currpoint + num,max);


             points = temp;

          }

    }

    int deleteAndEarn(vector<int>& nums) {

        multiset<int> points(nums.begin(),nums.end());

        int max = INT32_MIN;

        earn_points(points,0,max);

        return max;
    }
};
trincot
  • 317,000
  • 35
  • 244
  • 286
  • 2
    Since you are doing no manual memory management, read through the [Iterator Invalidation Rules](https://stackoverflow.com/questions/6438086/iterator-invalidation-rules) for the containers you are using and make sure you are not accidentally violating one of the rules. – user4581301 Feb 26 '20 at 18:43
  • 1
    Here is a near-miss duplicate that you can to use to help solve your problem: [Deleting elements from std::set while iterating](https://stackoverflow.com/questions/2874441/deleting-elements-from-stdset-while-iterating) – user4581301 Feb 26 '20 at 18:58
  • 1
    I think you may want `points.erase(it);` to be `it = points.erase(it);`. – Jesper Juhl Feb 26 '20 at 19:49
  • 1
    Some documentation to read: https://en.cppreference.com/w/cpp/container/multiset/erase – Jesper Juhl Feb 26 '20 at 19:50
  • 1
    Needs a bit more than just `it = points.erase(it);` If you advance the iterator through `erase` you do not want to advance it again with the `++it` in the `for`. – user4581301 Feb 26 '20 at 19:58

1 Answers1

2

Your problem is most likely here:

points.erase(it);

if(points.find(delete_num1)  != points.end())
      points.erase(delete_num1);

if(points.find(delete_num2)  != points.end())
      points.erase(delete_num2);

When you erase things from a multiset, it invalidates the iterator, so when you hit the iterator referencing something you've erased in your for... loop you're referencing something that no longer exists.

cschadl
  • 66
  • 1
  • 3
  • Correct, but fails to point out where the erased iterator is being reused. The glaring reuse is `++it` in the `for`'s iteration expression. I didn't look at the code past that so there could be more. – user4581301 Feb 26 '20 at 18:54