I have a hash table generated at runtime, populated by global variables.
inline A* global1 = new A();
inline A* global2 = new A();
inline A* global3 = new A();
std::map<A*, int> createMap() {
return std::map<A*, int>({{global1, 1}, {global2, 2}, {global3, 3}});
}
I want to add new entries to map
during runtime, meaning that I'll have to create new pointers to A
.
void doStuff(std::map<A*, int>& map) {
A* runTimeValue = new A();
map[runTimeValue] = 4;
}
However this opens up the program to memory leaks as I'll have to worry about deleting runTimeValue
when the map object finally goes out of scope and is deleted. I considered switching the map to std::map<std::shared_ptr<A>, int>
but working with std::shared_ptr<A>
is difficult as it has many different subclasses.
One solution I had was to wrap runTimeValue
in a shared_ptr so that it can automatically be deleted, and then continue using the raw pointer.
void doStuff(std::map<A*, int>& map) {
A* runTimeValue = new A();
std::shared_ptr<A> temp(runTimeValue);
map[runTimeValue] = 4;
}
Would this work? Do I need to store a reference to temp
till the map goes out of scope? Is there a better way of dealing with a mix of global and run time pointers where run time ones have to be deleted but globals do not?
Edit, example of "program" in use:
inline A* global1 = new A();
inline A* global2 = new A();
inline A* global3 = new A();
int main() {
while(true) {
std::map<A*, int> map = createMap();
doStuff(map);
doStuff(map);
doStuff(map);
}
}
You are a bit betwixt and between with this. What you are proposing won't end well. Assuming that you actually need a map of pointers...
If the map has sole ownership of the objects contained within it, use std::map<std::unique_ptr <A>, int>
. If it shares ownership with other parts of your code, use std::map<std::shared_ptr <A>, int>
.
Then, either way:
objects won't go away unexpectedly while still present in your map
objects will be cleaned up (or their reference count decremented) when you remove them from your map
For your global objects, you can create them with std::make_unique
or std::make_shared
as appropriate, rather than using new
. Then they can be managed the same way as everything else.