本文介绍了是公平的总是推荐std :: vector over realloc吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从:

我会先同意我的问题,同意 std :: vector 是更好的许多原因,我个人会总是选择使用它



, std :: vector 编辑)的等效内容。要澄清,我知道 std: :vector 的存储是连续的并且不会被分段,我的意思是分配和释放引起的内存空间的碎片, realloc 可以通过扩展现有分配来避免)。那么公平地总是推荐它 realloc ?非常小心,你不能写一些工作就像 std :: vector 但是使用C分配函数,它有可能增长其内存,而不移动其地址和复制现有元素,使其在分段和性能方面更好或更好?



相关(奖金问题!), t C ++等价于 realloc ?看起来像一个奇怪的事情,忽略在一个如此专注于性能的语言。在Bjarne的FAQ中的部分具有正确的标题(减去重点),但答案不解决为什么。这只是一个意外的遗漏吗?是否与 new / delete 如何工作有一些根本不兼容?



编辑:确定,所以我忽略了考虑C的妄想。 code> realloc - std :: vector 不能使用 >因为它只适用于POD,不会抛出等等。也许一个只有POD的容器是为了处理这种谬误,在某些情况下是一个好主意。在任何情况下,更有趣的问题变成:< std :: vector 受益于 realloc (或多或少)已在这里回答:





很遗憾,答案似乎是是的,但标准委员会没有投票。这是希望。

解决方案

直接比较



  | std :: vector | C内存函数
------------------------ + ------------------ + ------------------------
默认容量|未定义| undefined
default grow |对能力| undefined
确定性容量|可用|没有
确定性增长可用| no
deterministic mem.-move |可用| no
非POD类型|是| f *** ing no(*)
no-throw | no | yes

确定性mem-移动 确定性容量/ grow 。当 realloc 和 std :: vector 必须将存储的元素移动到新的内存位置。



我认为关于内存移动的(可用的)决定论在考虑移动(智能)任何类型的引用时是非常重要的。



/ p>






c $ c> realloc 会执行:

换句话说,所使用的内存是一块。 >

一个很大的区别是 realloc 实际上可以增加已分配的内存部分,而无需对其进行排序,不需要这样做( man 3 realloc ):



std :: vector 不仅包含 size ,还有一个 capacity 。如果你事先知道,你将需要一个大的向量,但是你不能初始化一切现在,你有权增加你的矢量的容量,如:

  std :: vector< T> vec(32); 
vec.reserve(1024);
// vec的大小为32,但保留了1024个元素的内存区域

不像 realloc ,重新分配发生的时刻可以是 std :: vector 。



要回答你的问题:因为有 std :: vector , realloc 需要。并且, realloc 不允许用于非POD类型;尝试直接使用 malloc , free 和 realloc -PODs产生未定义的行为。


From Bjarne Stroustrup's FAQ:

I'll preface my question by agreeing that std::vector is better for many reasons, and I personally would always choose to use it over writing my own dynamic arrays with C memory allocation.

But, std::vector fragments memory as it grows because C++ has no equivalent of realloc (edit To clarify, I know that std::vector's storage is contiguous and won't get fragmented, I mean fragmentation of the memory space caused by allocating and deallocating, which realloc can avoid by extending an existing allocation). So is it fair to always recommend it over realloc? With great care, couldn't you write something that works just like std::vector but using C allocation functions, which has the possibility to grow its memory without moving its address and copying existing elements, making it as good or better in terms of fragmentation and performance?

And relatedly (bonus question!), why doesn't C++ have an equivalent to realloc? It seems like an odd thing to omit in a language that is so focused on performance. The section in Bjarne's FAQ has exactly that title (minus emphasis), but the answer doesn't address the 'why'. Was it just an accidental omission? Is there some fundamental incompatibility with how new/delete work? Does it not really give the benefits it seems to in practice?

Edit: ok, so I had neglected to consider the C nastiness of realloc - std::vector can't be rewritten using realloc because it only works with PODs, doesn't throw and so on. Perhaps a POD-only container written to deal with the nastiness would be a good idea for some situations. In any case though, the more interesting question becomes: would std::vector benefit from a C++ equivalent of realloc, which has (more or less) been answered here:

Does std::vector *have* to move objects when growing capacity? Or, can allocators "reallocate"?

Sadly, the answer seems to be "yes, but the standards committee didn't vote it in". Here's hoping.

解决方案

Direct comparison

                        |  std::vector     | C memory functions
------------------------+------------------+------------------------
default capacity        | undefined        | undefined
default grow            | towards capacity | undefined
deterministic capacity  | available        | no
deterministic grow      | available        | no
deterministic mem.-move | available        | no
non-POD types           | yes              | f***ing no (*)
no-throw                | no               | yes

deterministic mem.-move follows from deterministic capacity/grow. It is when realloc and std::vector have to move their stored elements to a new memory location.

I think the (available) determinism with regards to memory moving is doubly important when you consider moving (smart) references of any kind.


Source

It does fragment memory as much as realloc does:

In other words, the memory used is in one piece.

The one big difference is that realloc can actually increase allocated memory portions without having ordered it to do so, however, it is not required to do so (man 3 realloc):

So it can increase the size, but is not required to.

A std::vector carries not only a size, but also a capacity. If you know beforehand you will need a big vector, yet you cannot initialize everything right now, you are entitled to increase the capacity of your vector like so:

std::vector<T> vec(32);
vec.reserve(1024);
// vec has size 32, but reserved a memory region of 1024 elements

So, unlike realloc, the moment when reallocations occur can be deterministic with std::vector.

To answer your question: Because there is std::vector, realloc is not needed. And, realloc is not allowed for non-POD types; attempts to use malloc, free and realloc directly on non-PODs yields undefined behaviour.

这篇关于是公平的总是推荐std :: vector over realloc吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 12:54