What is the best way to put large objects on the heap?
I am working on a project that needs to load many objects from a data file
and store them in memory. Since I have been told that stack space is rare
and larger amounts of data should be on the heap I put everything on the
heap. However, my impression is that I overdid it a little bit.
My current design looks like this:
class RoadMap
{
unique_ptr<set<unique_ptr<Node>>> allNodes;
void addNode(unique_ptr<Node> node)
{
this->allNodes->insert(std::move(node));
}
}
int main()
{
unique_ptr<RoadMap> map(new RoadMap());
// open file etc.
for (auto nodeData : nodesInFile)
{
map->addNode(unique_ptr<Node>(new Node(nodeData)));
}
}
From what I understand by now, this creates a lot of overhead because
there are many unique pointers involved that I think I do not need. If I
understand correctly, it should be sufficient to only have one unique
pointer barrier in the "pointer chain". However, I am unsure what the best
practice is to do this.
Option 1
class RoadMap
{
unique_ptr<set<Node>> allNodes;
void addNode (Node node)
{
this->allNodes->insert(node);
}
}
int main()
{
RoadMap map;
//open file etc.
for (auto nodeData : nodesInFile)
{
map.addNode(Node(nodeData));
}
}
The advantage of this seems to me that the RoadMap class itself is the
only one that needs to take care of heap allocation and does so only once
when creating the set.
Option 2
class RoadMap
{
set<Node> allNodes;
void addNode (Node node)
{
this->allNodes.insert(node);
}
}
int main()
{
unique_ptr<RoadMap> map(new RoadMap());
// open file etc.
for (auto nodeData : nodesInFile)
{
map->addNode(Node(nodeData));
}
}
Here the unique pointer is only in the main function meaning that the
users of the RoadMap class will need to know that this object can become
quite large and should be put on the stack. I don't think that this is an
overly nice solution.
Option 3
class RoadMap
{
set<unique_ptr<RoadMap>> allNodes;
void addNode(unique_ptr<Node> node)
{
this->allNodes.insert(std::move(node));
{
}
int main()
{
RoadMap map;
// open file etc.
for (auto nodeData : nodesInFile)
{
map.addNode(unique_ptr<Node>(new Node(nodeData)));
}
}
This solution uses many unique pointers which means that when deleting the
RoadMap many destructors and deletes will need to be called. Also the
RoadMap caller has to supply a unique_ptr when adding a node meaning that
he has to do the heap allocation himself.
Right now, I am favouring option 1 over the others. However, I have only
been coding C++ for a comparatively short time and am unsure whether I
fully understand the concepts behind memory management which is why I want
you to (in)validate my opinion. Am I correct in assuming that option 1 is
the best way to do this? Do you have any additional references to best
practices for this sort of thing?
No comments:
Post a Comment