从 Map 擦除后访问指针

Posted

技术标签:

【中文标题】从 Map 擦除后访问指针【英文标题】:Accessing pointers after erasing from Map 【发布时间】:2018-02-27 07:59:16 【问题描述】:

我的代码实现中的示例场景如下

我有一个定义为 map<int,map<int,object*>*> 的地图。堆中的内部映射有一个对象指针。

场景是,

在使用(处理)内部地图中的所有元素之后。我将使用迭代器擦除内部地图内容。但不会删除对象*。从地图中删除键后,我将进一步使用对象指针。

我的问题是,即使在地图中删除它之后,该对象* 是否还会存在。据我了解,是的,该对象在堆中,即使在地图中擦除后也可以使用它。但是在执行几分钟后,我在这个过程中面临随机崩溃。这让我在这里发布问题。

multimap<ULONG, Class*>::iterator it_top3 = InnerMap->begin();
if (InnerMap->size() >= classLimit)

    if (it_top3->first <= ClassObj->m_classSize)
    
        if (it_top3->second != NULL)
        
            delete it_top3->second;
            it_top3->second = NULL;
        
        InnerMap->erase(it_top3);
        InnerMap->insert(pair<ULONG, Class*>(ClassObj->m_classSize, ClassObj));

其次,在分析调试诊断时,it_top3-&gt;second = NULL; 行指向具有访问冲突异常的崩溃点。这里发生崩溃的可能原因是什么?

【问题讨论】:

如果你有一个指针容器,从容器中删除一个元素不会使指针或被指向的对象无效。它所做的只是从容器中移除元素。 使用 std::unique_ptr 或 boost::shared_ptr 代替标准指针可能是值得的。 【参考方案1】:

你不只是从地图上删除线

        delete it_top3->second;
        it_top3->second = NULL;

释放指针,这可能会导致崩溃。

只需调用InnerMap-&gt;erase() 即可完成您的预期。

【讨论】:

如果你推广 C++ 的 nullptr,我会 +1 ;) 从你的回答中,我的第一个问题得到了解决,即使在地图擦除后对象仍然存在。但是第二个问题是为什么我在示例代码中指定的地方会发生崩溃。会是什么原因? 第一:我建议删除nullptr 没有意义。 现在,回复 Sel_va:这真的很难说。但是我可以告诉您,如果您提到的某些访问冲突导致崩溃,那么它几乎不会出现在您的代码中出现错误的地方。在大多数情况下,您在其他地方做错了事并遇到了未定义的行为。

以上是关于从 Map 擦除后访问指针的主要内容,如果未能解决你的问题,请参考以下文章

使用指向值的原始指针从 std::list<Value> 中擦除?

指针数组内容在传递给 C 中的函数时被擦除

nor flash之擦除和写入

通过指针擦除 STL 向量

类型擦除成员函数指针的“正确”方法是啥?

双指针应用--快慢指针