有没有办法防止 std::vector 在发生调整大小时动态取消分配内存?

问题描述 投票:0回答:1

我想使用 std::vector 代替原始 C 数组,以避免弄乱我的代码。

然而,std::vector 的活力的缺点之一是无法可靠地假设底层数据保留在 RAM 中的同一位置。例如:

假设我有 3 个字符向量存储在 9 个字节的内存中:

A[0] A[1] A[2] | B[0] B[1] B[2] | B[0] B[1] B[2] | C[0] C[1] C[2]

考虑到 B 紧贴在 A 和 C 之间的位置,可以合理地假设,如果 B 的大小增加,整个内容将移动到内存中的不同位置,这与使用 std::vector 的实现相反任何非顺序的数据存储。我很高兴 std::vector 不做这种非顺序存储的事情,因为这意味着底层数据结构仍然是数组,这可以最大限度地提高效率。

在上述场景中 std::vector 如何移动 B 的问题与它在移动后所做的事情有关:它释放了 B 的 3 个项目先前所在的内存位置。这导致了我的代码中的一个错误,因为我在其他位置使用了指向向量的指针。当内存被释放时,这些指针在调整大小后不久就变得无效。随后出现分段错误。

我的问题:有没有办法阻止 std::vector 在重新调整时释放内存?即使内存开销因此增加,这在我的用例中也没有问题。

或者,您是否建议使用任何其他 C++ 数据结构来执行此操作?

c++ vector
1个回答
0
投票

除了使用大于

.reserve
所能得到的值来调用
vector
之外,
vector
不会为您执行此操作,因此,如果没有已知的最大可能大小,则
std::vector
不是一个选项。

听起来你想要

std::deque
在这里。它具有
std::vector
的所有大 O 性能保证(除了末尾的追加和弹出是 实际上
O(1)
,而不是摊销
O(1)
),并且只要它只增长,从不收缩,并且给定元素永远不会移动到新内存(因为在幕后,它分配更多不相邻的内存块,而不是重新分配单个连续块)。为此,它会付出更高的基线内存开销和所有操作的更高的fixed开销(例如,索引
std::vector
只需要追逐单个指针,而索引
std::deque
可能需要三个这样的指针追逐操作,但它将是一个固定三,不像
std::list
那样随集合大小缩放),但它通常足够快,并且它会给你带来你正在寻找的内存位置稳定性保证。

© www.soinside.com 2019 - 2024. All rights reserved.