在C ++中释放内存期间迭代器与指针有何不同
How is iterator different from a pointer during the deallocation of memory in C++
我有一个 class "DMRecSessionObj" 其对象是使用 new 动态分配并存储在映射中的。
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);
此时迭代器所在的代码块应该很小,并且迭代器本身超出范围,因此您无需对其进行任何操作即可将其清除。但是如果你真的想要,你可以将其类型的默认值分配回它。
我有一个 class "DMRecSessionObj" 其对象是使用 new 动态分配并存储在映射中的。
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);
此时迭代器所在的代码块应该很小,并且迭代器本身超出范围,因此您无需对其进行任何操作即可将其清除。但是如果你真的想要,你可以将其类型的默认值分配回它。