标准::矢量内存管理
std::vector memory management
我所知,std::vector
为它将包含的数据保留了一些内存,如果该内存已满,它将所有数据复制到一个新的更大的内存块中。
例如,如果向量包含 2 个元素,则内存如下所示:
DD--XX----- D for vector's data, - for empty, X for other data
如果我添加两个元素,它将变成这样:
DDDDXX-----
但是如果我尝试添加另一个元素,矢量将复制所有元素并释放以前的内存:
----XXDDDDD
我说的对吗?
现在我不希望向量将成员复制到另一个内存块,所以我想知道他什么时候这样做。可能吗?例如,使用在发生这种情况时引发异常的插入函数
是的,您已经正确理解了std::vector
的行为。
您可以观察std::capacity
- 它为您提供了向量的容量大小,这意味着 - 在下一次重新分配之前,向量可以如何容纳元素。你可以做类似的事情
std::vector< type >::size_type remaining_places = v.capacity() - v.size();
您无法完全阻止这种情况,但您可以随时使用std::vector::reserve
更改矢量的容量。
std::vector 的实际规范是这样的
template < class T, class Alloc = allocator<T> > class vector;
其中Alloc
是委派给以分配原始内存的对象的类型。
如果要截获向量执行的大小调整操作,请提供适当定制的分配器。 定制的分配器(一个类,可能是模板化的(将需要允许保留或设置大小的第一个操作,但在后续调整大小尝试时引发异常。 查找模板化std::allocator
(以及C++',std::allocator_traits
(,了解您的定制分配器必须支持的接口规范。
我说的对吗?
有点。
您的图表使它看起来像矢量重新分配,否则会导致它们运行到其他分配的内存中。那不是真的。矢量在分配的内存不足时重新分配。可能是这个
DD--------
DDD-------
------DDDD
即使没有任何X
.
这里的关键是向量执行的预分配。假设向量的容量为 4:
std::vector<int> v;
v.reserve(4);
v.push_back(999);
v.push_back(998);
v.push_back(997);
v.push_back(996);
这可能会导致:
-------XX---------
PPPP---XX--------- set capacity
DPPP---XX--------- add element
DDPP---XX--------- add element
DDDP---XX--------- add element
DDDD---XX--------- add element
DDDD---XX--PPPPPPP increase capacity; requires new allocation...
DDDD---XX--DDDDPPP ... and copying of data ...
-------XX--DDDDPPP ... and de-allocation of the original memory
等等。
现在我不希望向量将成员复制到另一个内存块,所以我想知道他什么时候这样做。可能吗?例如,使用在发生这种情况时引发异常的插入函数
不是真的,但您可以简单地将myVector.size()
与myVector.capacity()
进行比较并自己抛出异常,而不是在两者相等时push
_back
。这将防止向量本身通过重新分配和复制来处理这种情况。
这听起来有点像您希望矢量尽可能多地就地增长,然后在进程内存中的空间不足时抛出。但是,据我所知,没有操作系统级别的支持,当然也没有C++可以访问的内容。(请注意,即使是realloc
也可能移动数据。你可以发明一种新型的计算机来做到这一点。从理论上讲,编写池分配器可以做到这一点,但为什么呢?这是大量的工作和令人惊讶的语义——据我所知——基本上没有任何好处。
指定std::vector
应将元素存储在连续内存中。这意味着,如果附加的值多于连续可用的值,它将在其他地方分配一个更大的连续块,并将值从旧内存块移动到新块。这是正确的行为,您不能或不应该对此采取任何措施。
为了具体回答您的问题,向量将在以下情况下为"满">
vector.size() == vector.capacity()
在此点之后的单个push_back
或emplace_back
(等(将需要在其他地方进行另一次分配,并且您会注意到.capacity()
的价值会增加。
std::vector 将至少管理足够的内存来容纳其中的对象。
如果您添加另一个对象导致其空间不足,它将自动增长 - 这是设计使然,无法预防,预测或检测。
如果您的对象是移动感知的,它们将被std::move
到新内存中的位置,而不是复制。
矢量中的所有对象都是连续的 - 永远不会有任何间隙(除了对齐要求要求的填充(。
如果从中间删除某些项,则末尾的项将向下移动,以便向量仍包含连续项。
如果你想防止向量增长超过一定大小,你必须为它编码(将向量包装在另一个类中?
您可以使用std::vector::reserve()
在矢量中预先保留空间
- 当vector是tje全局变量时,c++中vector的内存管理
- 当分配一个字符串值并稍后通过分配另一个值进行更改时C++如何管理内存?
- 我有一个线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)错误.我认为这是由于内存管理不好.我可以
- 可以通过非原始指针来增强容器矢量管理内存
- 如何使用 std::vector<std::tuple<A,B>> 来管理内存(调整大小、保留,...),但实际上将 As 保留在 B 之前,连续
- 线程管理内存泄漏
- 通过读取文件创建映射<字符串,矢量>时如何管理内存<string>
- 管理内存C++
- ptr_vector如何管理内存
- 在C++Builder/Firemonkey中使用表单创建来管理内存
- 如何正确管理内存(运行时)C++
- 在Node.js中使用Native Abstractions时,如何管理内存
- ostream是如何管理内存的
- C++中管理内存泄漏的问题
- OpenCL:在 CPU 上而不是在 GPU 上更正结果:如何正确管理内存
- deque是如何管理内存的
- 用c++/cli互操作管理内存
- 如何衡量管理内存所花费的时间
- (加速C++)章节管理内存
- 如何在此场景中管理内存