繁体   English   中英

std :: vector内存管理

[英]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_backemplace_back (等)将需要在其他位置进行其他分配,并且您会注意到.capacity()的值将增加。

std :: vector将管理至少足够的内存以在其中容纳对象。

如果添加另一个导致空间用完的对象,它将自动增长-这是设计使然,无法防止,预测或检测到。

如果您的对象可移动,它们将被std::move新内存中,而不是被复制。

向量中的所有对象都是连续的-永远不会有任何间隙(除了对齐要求所要求的填充)。

如果从中间删除一些项目,则末尾的项目将向下移动,以便矢量仍包含连续的项目。

如果要防止向量增长到一定大小,则必须对此进行编码(将向量包装在另一个类中?)

您可以使用std::vector::reserve()在向量中保留空间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM