Reputation: 882
I have an unordered_map of objects. Each object, in its destructor, browses the unordered map to find other objects, and then tweaks these other objects. This will fail if the other objects are zombie objects, but if the other objects are entirely removed from the unordered_map, there is no problem.
My questions:
Upvotes: 2
Views: 1602
Reputation: 38
I think i found a decent solution. You could possibly encapsulate an unordered_map in a class and use its distructor to raise a flag and detect it as an edge case in the destructor of the object that is typaram in the hash table. Like this:
template<typename K, typename V>
struct hash_table
{
unordered_map<K, V> map;
bool is_being_deleted = false;
~hash_table()
{
is_being_deleted = true;
}
};
struct PageRefrence
{
string str;
int page;
hash_table<string, PageRefrence>& refTable;
~PageRefrence()
{
if (refTable.is_being_deleted == true) // When the map is in the procces of deletion
return;
else
{ // Normal case
auto x = refTable.map.find(str);
cout << (*x).second.page;
}
}
};
int main()
{
hash_table<string, PageRefrence> refTable;
refTable.map.insert({ "HELP",{"HELP",42,refTable} });
}
Upvotes: 0
Reputation: 16156
The lifetime of an object of type T ends when [...] if T is a class type with a non-trivial destructor (12.4), the destructor call starts [...]
[§ 3.8/1 N4431]
And, further down
The properties ascribed to objects throughout this International Standard apply for a given object only during its lifetime
[§ 3.8/3 N4431]
And finally
[...] after the lifetime of an object has ended [...] any pointer that refers to the storage location where the object will be or was located may be used but only in limited ways. [...] The program has undefined behavior if [...] the pointer is used to access a non-static data member or call a non-static member function of the object [...]
[§ 3.8/5 N4431]
So, since you must have some kind of reference (e.g. a pointer, or a real reference, which I'd count as pointer here, too) to the map, and its lifetime has ended, accessing a member function (to get an iterator for example) will - as far as I'd read this part of the standard - lead to undefined behaviour.
I was also looking at the part of the standard about unordered containers and containers in general, and couldn't find an exception to the above or any clue about the state during destruction.
So: Don't do this. Neither with unordered containers, nor with any other object.
BTW: What kind of tweaking makes any sense when you do it on objects that will be destructed moments thereafter?
Upvotes: 3