加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 将大型对象放在堆上的最佳方法是什么?

发布时间:2020-12-16 09:46:58 所属栏目:百科 来源:网络整理
导读:我正在开发一个项目,需要从数据文件中加载许多对象并将它们存储在内存中.因为我被告知堆栈空间很少,并且堆上的数据量应该更多,所以我将所有内容放在堆上.但是,我的印象是我过度了一点. 我目前的设计如下: class RoadMap{ unique_ptrsetunique_ptrNode allNo
我正在开发一个项目,需要从数据文件中加载许多对象并将它们存储在内存中.因为我被告知堆栈空间很少,并且堆上的数据量应该更多,所以我将所有内容放在堆上.但是,我的印象是我过度了一点.

我目前的设计如下:

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)));
    }
}

从我现在所理解的,这会产生很多开销,因为我认为我不需要涉及许多独特的指针.如果我理解正确,那么在“指针链”中只有一个唯一的指针屏障就足够了.但是,我不确定这样做的最佳做法是什么.

选项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));
    }
}

这样做的好处在于,RoadMap类本身是唯一需要处理堆分配的类,并且在创建集时只执行一次.

选项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));
    }
}

这里唯一的指针只在main函数中,这意味着RoadMap类的用户需要知道这个对象可以变得非常大并且应该放在堆栈中.我不认为这是一个非常好的解决方案.

选项3

class RoadMap
{
    set<unique_ptr<Node>> 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)));
    }
}

此解决方案使用许多唯一指针,这意味着在删除RoadMap时,需要调用许多析构函数和删除操作.此外,RoadMap调用者在添加节点时必须提供unique_ptr,这意味着他必须自己进行堆分配.

现在,我赞成选项1而不是其他选项.但是,我只在相当短的时间内编写C语言,并且不确定我是否完全理解内存管理背后的概念,这就是为什么我希望你(在)验证我的观点.假设选项1是最好的方法,我是否正确?对于这类事情,您是否还有其他最佳实践参考?

解决方法

给Node一个移动构造函数并移动赋值运算符(使集合上的操作便宜),然后使用选项1和2的混合.std :: set将已经堆分配其内容,因此您不必担心分配堆上的RoadMap.注意addNode中的额外std :: move以允许将节点移动到集合中.

class RoadMap
{
    set<Node> allNodes;

    void addNode (Node node)
    {
        allNodes.emplace(std::move(node));
    }
};

int main()
{
    RoadMap map;
    // open file etc.
    for (const auto& nodeData : nodesInFile)
    {
        map.addNode(Node(nodeData));
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读