0

I have a code snippet that uses std::map::emplace to insert elements into a map. The key is an internal version of a unique_ptr.

The standard states:

The element may be constructed even if there already is an element with the key in the container, in which case the newly constructed element will be destroyed immediately.

In the following snippet, if the wrapper is constructed/destructed, it will correctly take destroy the naked pointer. If it is not, the object will be leaked. The snippet is just an example.

class Wrapper {
public:
    Wrapper(int* param):
        value(param) {}
    ~Wrapper() { delete value;}
    bool operator<(const Wrapper& other) const { return *value < *other.value;}

private:
    int * value;
};

int main()
{
  std::map<Wrapper, int> map;

  {
    int *key = new int(100);
    map.emplace(key, 5);
  }

  {
    int *keyDuplicate = new int(100);
    map.emplace(keyDuplicate, 10);
  }
}

The handling seems to be implementation dependant. I could check the return value and destroy the object if it was a duplicate. But if the object was constructed and deleted, I would be deleting the pointer twice.

vegi
  • 197
  • 9
  • 2
    Where are your comparison operators? How did this compile without them? – Nicol Bolas Sep 18 '17 at 14:31
  • 3
    Why on earth using a _naked pointer_ as key?? – user0042 Sep 18 '17 at 14:31
  • [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)? – The Quantum Physicist Sep 18 '17 at 14:32
  • 2
    We can't know whether or not they keys are duplicates (equivalent) without seeing the comparison operators. – François Andrieux Sep 18 '17 at 14:37
  • Umm.. what is the question here? You split memory management responsibility and base on implementation defined behaviour saying there might be problems... Yes. Avoid the design, it's clearly bad if you can't make a simple example work without some workarounds or abstractions. Am I missing something? – luk32 Sep 18 '17 at 14:38
  • Make correct snippet, your would not compile and violates rule of 3 – Slava Sep 18 '17 at 14:48
  • Possible violation of the [rule of 5](https://stackoverflow.com/questions/4782757/rule-of-three-becomes-rule-of-five-with-c11)? – Mark Ransom Sep 18 '17 at 14:49
  • I added the comparison operator – vegi Sep 18 '17 at 14:52
  • Your pointer will dangle. I don't know if there is a direct clause saying it will, but the one you quoted alongside some others indirectly mandates that. Don't do this. If you must, use `std::shared_ptr`, or manage your memory properly. – Passer By Sep 18 '17 at 15:20

0 Answers0