0
class A
{
  public:
    A(int i)
    {
      x = new int(i);
    }
    ~A()
    {
      if (x != NULL)
      {
        delete x;
        x = NULL;
      }
    }
  private:
    A();
    int *x;
};

void f()
{
  {
    map<int,A> myMap;
    A a(2);
    // myMap[7] = a;  // cannot access default ctor
    pair<int, A> p(7,a);
    myMap.insert(p);
  }
}

The problem here is that upon scope exit the destructor of A is called twice. Probably the first time to destruct A a(2) and the 2nd time to destruct some temp object created by map. This causes an exception since x is not allocated.

  1. Why does the command myMap[7] = a construct a new A and why does it use the default ctor?
  2. What can be a solution?
2
  • You must declare copy constructor, and operator=, you should also declare move constructor. Commented Feb 7, 2019 at 10:54
  • 1
    Have you had a look at this thread? Commented Feb 7, 2019 at 10:55

1 Answer 1

1
  1. Because the subscript operator returns a reference to an element in the map, which you then assign to. In order to have an object to refer to, and assign to, that element must be constructed (unless an element already happens to exist for the given key).

  2. a. To avoid the copy: emplace the A directly into the map instead of copying a local variable.

    b. While getting rid of unnecessary copies is a good thing, it is not a substitute to fixing your class. Either make the class have well defined behaviour after assignment and copying, or make the class non copyable and non assignable. For more info, see rule of three (five).

    You should never have bare owning pointers. Using a unique pointer instead would fix the class in an elegant way.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.