在C++中释放内存期间,迭代器与指针有何不同

How is iterator different from a pointer during the deallocation of memory in C++

本文关键字:迭代器 指针 何不同 C++ 释放 内存      更新时间:2023-10-16

我有一个类"DMRecSessionObj",其对象使用new动态分配并存储在map中。

static std::map<string,DMRecSessionObj*> mapExpSessData;
DMRecSessionObj* dmRecSessObj = new DMRecSessionObj(atoi(p_callNum),atoi(p_totCalls), sessionKey);
mapExpSessData.insert(std::pair<string,DMRecSessionObj*>(sessionKey,dmRecSessObj));

在释放内存的过程中,我使用以下显而易见的方法

delete dmRecSessObj;
dmRecSessObj = NULL; //to prevent it from being a dangling pointer

但是在尝试使用迭代器释放内存时,我有点困惑,如下所示:

std::map<std::string,DMRecSessionObj*>::iterator itr_del = mapExpSessData.find(tmp_sessionId);
if (itr_del != mapExpSessData.end()){
mapExpSessData.erase(tmp_sessionId);
delete itr_del->second;
}

在这种情况下,迭代器itr_del是否应该以某种方式设置为 NULL?如果未设置为 NULL,普通指针可能会导致指针悬空,在这种情况下迭代器的行为如何?在这种情况下,还需要做更多的事情才能安全吗? 请指教。

谢谢。

调用mapExpSessData.erase(tmp_sessionId);后,映射中itr_del指向的节点已被删除。 然后,调用delete itr_del->second;是未定义的行为,因为您尝试访问已释放的内存。

您需要先删除映射中的值,然后再删除映射中的节点:

delete itr_del->second;
mapExpSessData.erase(itr_del);

此时迭代器所在的代码块应该很小,并且迭代器本身超出了范围,因此您无需对其进行任何操作即可将其清除。 但是,如果您确实愿意,则可以将其类型的默认值重新分配给它。