{"action":"created","issue":{"url":"https://api.github.com/repos/cocos2d/cocos2d-x/issues/13656","labels_url":"https://api.github.com/repos/cocos2d/cocos2d-x/issues/13656/labels{/name}","comments_url":"https://api.github.com/repos/cocos2d/cocos2d-x/issues/13656/comments","events_url":"https://api.github.com/repos/cocos2d/cocos2d-x/issues/13656/events","html_url":"https://github.com/cocos2d/cocos2d-x/issues/13656","id":104238527,"number":13656,"title":"cocos2d::Map may cause Dangling Pointers when inserting Ref Object which already exist in the Map","user":{"login":"c3076802","id":3726167,"avatar_url":"https://avatars.githubusercontent.com/u/3726167?v=3","gravatar_id":"","url":"https://api.github.com/users/c3076802","html_url":"https://github.com/c3076802","followers_url":"https://api.github.com/users/c3076802/followers","following_url":"https://api.github.com/users/c3076802/following{/other_user}","gists_url":"https://api.github.com/users/c3076802/gists{/gist_id}","starred_url":"https://api.github.com/users/c3076802/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/c3076802/subscriptions","organizations_url":"https://api.github.com/users/c3076802/orgs","repos_url":"https://api.github.com/users/c3076802/repos","events_url":"https://api.github.com/users/c3076802/events{/privacy}","received_events_url":"https://api.github.com/users/c3076802/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":12,"created_at":"2015-09-01T10:44:58Z","updated_at":"2015-09-10T03:46:57Z","closed_at":null,"body":"cocos2d::Map may cause Dangling Pointers when inserting Ref Object which already exist\r\nCCMap  line 274\r\n```C++\r\n    void insert(const K& key, V object)\r\n    {\r\n        CCASSERT(object != nullptr, \"Object is nullptr!\");\r\n        erase(key);\r\n        _data.insert(std::make_pair(key, object));\r\n        object->retain();\r\n    }\r\n```\r\nFor example\r\nObject A already exist in Map B, and Map B has the very last reference of Object A. The code above will release Object A and Object A will be deleted, then Map B holds a Dangling Pointer.\r\n\r\nHow about retain the input object first, or check if the input object exist?\r\n"},"comment":{"url":"https://api.github.com/repos/cocos2d/cocos2d-x/issues/comments/139108367","html_url":"https://github.com/cocos2d/cocos2d-x/issues/13656#issuecomment-139108367","issue_url":"https://api.github.com/repos/cocos2d/cocos2d-x/issues/13656","id":139108367,"user":{"login":"c3076802","id":3726167,"avatar_url":"https://avatars.githubusercontent.com/u/3726167?v=3","gravatar_id":"","url":"https://api.github.com/users/c3076802","html_url":"https://github.com/c3076802","followers_url":"https://api.github.com/users/c3076802/followers","following_url":"https://api.github.com/users/c3076802/following{/other_user}","gists_url":"https://api.github.com/users/c3076802/gists{/gist_id}","starred_url":"https://api.github.com/users/c3076802/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/c3076802/subscriptions","organizations_url":"https://api.github.com/users/c3076802/orgs","repos_url":"https://api.github.com/users/c3076802/repos","events_url":"https://api.github.com/users/c3076802/events{/privacy}","received_events_url":"https://api.github.com/users/c3076802/received_events","type":"User","site_admin":false},"created_at":"2015-09-10T03:46:57Z","updated_at":"2015-09-10T03:46:57Z","body":"@seivan @c3076802 @stevetranby @WenhaiLin\r\nI suggested before \"Of course I could retain the object then insert then release or check if the object already inserted\". \r\nI did consider fix similar to @stevetranby 's, but I changed my mind later, here are the reason. \r\n1. The problem is actually self-assigning, it should be solved by comparing self with input ( to make the problem clear).\r\n2.  @stevetranby 's fix need more function ( retain() ) call than mine fix; mine fix is actually an inline version of erase with extra comparison.\r\n\r\n'''C++\r\n    size_t erase(const K& k)\r\n    {\r\n        auto iter = _data.find(k);\r\n        if (iter != _data.end())\r\n        {\r\n            iter->second->release();\r\n            _data.erase(iter);\r\n            return 1;\r\n        }\r\n        \r\n        return 0;\r\n    }\r\n'''\r\n\r\nThx.\r\n"}}