gpt4 book ai didi

memory-management - std::vector、std::map 和内存问题

转载 作者:行者123 更新时间:2023-12-04 07:50:25 28 4
gpt4 key购买 nike

我正在编写将数据库中的行插入向量的代码。然后将向量存储在 std::map 中。这种架构允许我根据映射键对数据集(向量)进行逻辑分区。

在我的代码中,我将从 std::map 检索数据集(即向量),向其中添加/删除行或对其执行一些其他逻辑,然后将向量粘贴回 map 中(所有这些在 while() 循环中继续)。

我有两个问题,这两个问题都与(可能)存储在向量中的大量元素有关。向量可以包含从几十到几万个元素的任何内容。我无法事先知道,将从数据库中检索多少条记录。因此,std::vector 的内存管理方案(即 alloc/dealloc)就变得非常重要,以便有效地使用内存,避免不必要的(内存)碎片:

我的问题是:

  1. 考虑到一行可以存储的潜在大量元素,理想情况下我想从内存池中分配/释放。但我不知道如何将 std::vector 与内存池一起使用,我不知道这是否会变得不必要地复杂。如果那是矫枉过正(或太复杂),那么我的另一个想法是在第一次创建向量时预先分配一 block 固定的内存。但这也可能过于简单化,因为从一个向量实例到另一个向量实例,元素的数量可能会有很大差异——导致(内存)碎片等,更不用说内存使用效率低下。

    这里推荐的方法是什么?

  2. 鉴于 std::map(所有 STL 容器 IIRC)存储值元素的副本这一事实,制作包含数万个元素的向量副本的前景是完全错误的。因此,我正在考虑编写一个围绕 STL::map 的 SmartPointerMap 包装器,然后存储指向向量而不是实际向量的指针。

    我走对了吗?如果否,有什么更好的解决方案。?如果是,是否有我可以使用的 boost 库(而不是编写我的 SmartPointerMap 类模板)?

[编辑]

我正在使用 gcc 4.4.1 在 Linux (Ubuntu 9.10) 上构建

最佳答案

假设您使用 vector 作为 map 的 data_type 而不是 key_type,您可以在不复制数据的情况下就地修改数据. std::map::operator[]() 返回对非 const data_type 的引用,以及从 std 的非 const 版本返回的迭代器::map::find() 允许您修改数据。

如果更改数据时需要更改 key 怎么办?您可以使用 std::swap() 将数据从一个向量移动到另一个向量,而无需复制。

不要忘记,当你删除元素时,vector 不会减少它的 capacity()。此外,vector 通常会分配比您需要的更多的 capacity(),因此 push_back() 需要摊销的常数时间。对于非常大的向量,如果您不小心,这些行为可能会显着增加程序的内存使用量。

如果您使用 vector 作为 map 的 key_type 并且 map 具有非常大的键,那么指针或智能指针可能会有所帮助。但是,如果是这种情况,您必须确保不要修改映射值之一所指向的键的内容,因为 std::map 并非旨在处理该问题。

至于自定义分配器的想法,首先让您的代码使用标准分配器,然后看看它是否足够快。使用标准分配器可能没问题。如果您的代码使用标准分配器不够快,请配置文件以查看实际花费的时间(它可能在其他地方,例如数据库代码)。如果你写了一个自定义分配器并且你从不将它与标准分配器进行比较,你将不知道你的自定义分配器是否真的是一种改进;它可能比标准分配器慢得多。

关于memory-management - std::vector、std::map 和内存问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2306005/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com