STL向量是realloc的更好版本吗?

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

在C++中,我相信,处理重新分配的更好方法是使用STL向量,因为它保证了连续的存储位置。

我有几个问题要理解其中的区别:

  1. 有没有什么场景我需要更喜欢 realloc 而不是向量?
  2. 还有什么(除了向量)相当于C++中的realloc吗?

谢谢,

c++ stl vector realloc
5个回答
17
投票

只是

vector
,保证有连续的内存。不是其他人。

realloc
是一个C内存管理函数。不鼓励在 C++ 代码中使用它。 Stroustrup 告诉您原因:为什么 C++ 没有与 realloc() 等效的函数?

但是,realloc() 只能保证对由 malloc() (和类似函数)分配的包含没有用户定义的复制构造函数的对象的数组起作用。另外,请记住,与天真的期望相反,realloc() 有时会复制其参数数组。


11
投票

C 函数集(malloc、calloc、realloc、free)是原始内存操作。他们将在内存中创建/修改/释放给定的缓冲区,但内存将没有类型,并且不会调用构造函数。

C++ 没有 realloc 的等效项,但只有通过使用 new/new[]delete/delete[] 来实现与 malloc/free 等效的类型安全。 C++ 版本将从系统获取内存通过调用适当的构造函数来初始化它。使用 delete 将调用对象的析构函数,然后释放内存。 C 和 C++ 版本不兼容,如果您使用 malloc 获取内存(即使您在收到的内存上调用就地构造函数),则无法使用 delete/delete[] 释放它,因为这是未定义的行为。

在 C++ 中使用

realloc 可能不安全,因为它会将对象从一个内存区域按位复制到下一个内存区域。有时,您的对象无法正确处理内存移动(假设您的对象既有属性又有对其的引用,按位移动后,引用将指向旧位置而不是真正的属性)。在 vector 中,每当内存需要增长时,都会使用 new[] 获取新的内存区域,然后使用适当的 C++ 操作将所有对象复制到(或复制构造在)新位置,然后再删除旧元素.

每当

vector的大小(保留大小,未使用的大小)增长时,它将创建一个完整的新内存区域并move所有对象。另一方面,如果指针后面没有足够的连续空间来“增长”内存块,则 realloc 只会将内存块移动到另一个位置。 矢量 不会减小尺寸。绝不。当您清除元素时,保留的内存仍然保留。 最后,即使对于 POD 类型(可以安全地使用类似 C 的构造来移动),vector

中的抽象级别也比 realloc 更高。与

vector 等效的是一个结构体,它保存指向内存缓冲区的指针、已使用的元素计数和保留(缓冲区大小)以及处理根据需要获取更多内存并在每次操作时更新索引的函数集.

连续内存也由 realloc 保证,因此这不是不使用它的理由。

8
投票
但是,我更喜欢在 C++ 中使用向量,因为它处于更高的抽象级别,因此它使代码更容易编写。

我认为在数组类型场景中使用 realloc(通过向量)的唯一可能原因是原始速度。它

可能

会更快。我强调“可能”这个词 -

测量,不要猜测! 但是,您必须处理自己的重新分配,这是更多的工作。如果我可以交付它并更快地获得报酬,我宁愿代码运行得慢一点(当然,假设它仍然运行得足够快)。

std::vector 的主要好处之一是,当它在内部从自然增长中重新分配自身时,它会选择比当前大小大 2 倍的大小(通常 - 但始终是一个常数乘数)。这意味着 Push_back 的成本摊销为 O(1)。

5
投票
Realloc 可以让您更好地控制如何分配内存,但能力越大,责任越大。如果你所做的一切相当于push_back,并且每次添加元素时都重新分配,那么每次添加到数组时

可能

都是O(N)操作。

我猜这只是一个向量。

1
投票
我还没见过有人建议在 C++ 中使用 realloc。

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