是否有必要将动态数组的容量加倍?

2023-11-22

当在 C 中创建自动扩展数组(如 C++ 的 std::vector)时,通常(或者至少是常见的建议)在每次填充时将数组的大小加倍,以限制调用的数量realloc为了尽可能避免复制整个数组。

例如。我们首先为 8 个元素分配空间,插入 8 个元素,然后为 16 个元素分配空间,再插入 8 个元素,再分配 32 个元素,等等。

But realloc如果可以扩展现有的内存分配,则不必实际复制数据。例如,以下代码在我的系统上仅执行 1 个副本(初始 NULL 分配,因此它不是真正的副本),即使它调用realloc10000次:

#include <stdlib.h>
#include <stdio.h>

int main()
{
    int i;
    int copies = 0;
    void *data = NULL;
    void *ndata;

    for (i = 0; i < 10000; i++)
    {
        ndata = realloc(data, i * sizeof(int));
        if (data != ndata)
            copies++;
        data = ndata;
    }
    printf("%d\n", copies); 
}

我意识到这个例子非常临床 - 现实世界的应用程序可能会有更多的内存碎片并且会做更多的副本,但即使我在realloc循环,如果有 2-4 个副本,它的表现只会稍微差一些。

那么,“倍增法”真的有必要吗?直接打电话不是更好吗realloc每次将元素添加到动态数组时?


您必须从代码中退一步,抽象地思考一下。开发动态容器的成本是多少?程序员和研究人员不会考虑“这花了 2 毫秒”,而是考虑了渐进复杂性:考虑到我已经拥有了,增长一种元素的成本是多少n元素;这是如何改变的n增加?

如果您仅以恒定(或有界)数量增长,那么您将必须定期移动所有数据,因此增长成本将取决于容器的大小,并随着容器的大小而增长。相比之下,当您以几何方式增长容器时,即multiply它的大小乘以一个固定的因子,每次它满了,那么expected插入成本实际上是独立的元素的数量,即constant.

当然不是always恒定,但它是摊余常数,这意味着如果您继续插入元素,那么每个元素的平均成本是恒定的。你时不时地必须成长和移动,但随着你插入越来越多的元素,这些事件变得越来越罕见。

我曾经问过C++ 分配器的增长是否有意义,以这样的方式realloc做。我得到的答案表明,非移动的生长行为realloc当你渐进地思考时,实际上有点转移注意力。最终你将无法再成长,你将不得不移动,因此为了研究渐近成本,是否realloc有时可以是空操作,也可以不是。 (此外,不动的增长似乎让现代的、基于竞技场的分配者感到不安,他们期望所有的分配都具有相似的规模。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否有必要将动态数组的容量加倍? 的相关文章

  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • C:数据结构对齐

    我正在处理结构 并且有几个关于它们的问题 据我了解 结构变量将按顺序放置在内存中 块 字 的长度取决于机器架构 32 位 4 字节 64 位 8 字节 假设我们有 2 个数据结构 struct ST1 char c1 short s cha
  • Java:如何原子地替换映射中的所有值?

    我在多线程环境中有一个有状态 bean 它将其状态保存在映射中 现在我需要一种方法来在一个原子操作中替换该映射的所有值 public final class StatefulBean private final Map
  • WinAPI 和 UTF-8 支持

    关于 UTF 8 支持和各种 Win32 API 的快速问题 在典型的C MFC项目中 MessageBox 是否可以显示UTF 8编码的字符串 谢谢 安德鲁 快速回答 不 更长的答案 如果字符串仅包含常规 ANSI 字符 例如美国英语 则
  • MS Access 中多值字段的替代方案

    相关问题 多值字段是个好主意吗 我知道多值字段类似于多对多关系 在 MS Access 应用程序中替换多值字段的最佳方法是什么 我有一个具有多值字段的应用程序 我不确定如何消除这些并以单值字段的形式实现完全相同的逻辑 当我想将多值关系转变为
  • 在 java.util.logginglogging.properties 文件中,“handlers”和“.handlers”之间有什么区别?

    在LogManager的文档中 Handlers属性的设置如下 财产 处理者 这定义了空格或逗号分隔 要加载和注册的处理程序类的类名列表 根 Logger 上的处理程序 名为 的 Logger 属性 handlers 这定义了一个空格或逗号
  • 从 SqlDependency 获取数据

    我有一个表和一个正在等待新插入的 SqlDependency OnChange 根据我的需要触发 但我不明白是否可以获得导致数据库更改的行 SqlDependency sql命令 SqlCommand cmd new SqlCommand
  • 我的 ASP.NET App_code 更改没有被拾取(或被缓存??)

    帮助 我在 根级别 App Code 目录下有一个 cs 文件 用于检索所请求 URL 的正确模板 它链接到我们自己的内容管理数据库 最初 它工作正常 我可以对其进行更改 并且 Web 应用程序可以正常接收它们 然后发生了一些事情 不知道是
  • 无法使用 MPMoviePlayerController 从视频中获取多个图像。操作系统状态-12433

    我正在尝试使用 MPMoviePlayerController 从选定的视频文件中提取多个图像 下面是我写的代码 movie MPMoviePlayerController alloc initWithContentURL info obj
  • “dlsym”的库在哪里

    我收到此链接器错误 system core libacc tests main cpp 42 error undefined reference to dlsym 你能告诉我 ubuntu 9 10 上包含 dlsym 库的库在哪里吗 谢谢
  • CUDA PTX 代码和寄存器内存的混淆

    当我尝试管理内核资源时 我决定研究一下 PTX 但有一些事情我不明白 这是我编写的一个非常简单的内核 global void foo float out float in uint32 t n uint32 t idx blockIdx x
  • 控制 $expand 请求返回的内容

    所以 使用ODataController 如果有人这样做 你可以控制返回的内容 odata Foos 42 Bars 因为您会被叫到FoosController像这样 public IQueryable
  • 将 java.lang.reflect.Method 转换为函数式接口

    很难找到该主题的任何线索 我能找到的只是有关将一个函数接口转换为另一个函数接口的问题以及一些有关 Java 类型转换的文章 不是我要找的 This问题是关于转换lambda Method我想要相反的 转换Method任何功能接口 例如Con
  • 如何禁用 Maven 阻止外部 HTTP 存储库?

    自版本 3 8 1 起 Maven 默认阻止外部 HTTP 存储库 请参阅https maven apache org docs 3 8 1 release notes html 有没有办法禁用它或使存储库免受此规则的约束 我找到了一个解决
  • 如何将tensorflow 2.0估计器模型转换为tensorflow lite?

    我下面的以下代码生成常规张量流模型 但是当我尝试将其转换为张量流精简版时 它不起作用 我遵循了以下文档 https www tensorflow org tutorials estimator linear1https www tensor
  • addGlobalMonitorForEventsMatchingMask 不起作用

    我在获取辅助应用程序 开发案例中的 XCode 来捕获全局 keyDown 事件时遇到问题 我见过很多类似下面的代码示例 但这对我来说在 10 9 4 上不起作用 import
  • 如何将整个图像作为壁纸适合屏幕上

    我正在开发一个应用程序 它从图库中选择一张图像 然后将该图像设置为壁纸 但这里的问题是 只有部分图像设置为壁纸而不是整个图像 但我想将整个图像设置为壁纸 你能告诉我该怎么做吗 这是我的代码 public class Scaleimage e
  • C++11 thread_local 变量自动静态吗?

    这两个代码段有区别吗 void f thread local vector
  • 使用 if 语句设置 javascript 变量 - 'var = x' 应该在 IF 内部还是外部?

    这可能是一个基本问题 但我很难找到答案 您想根据 var A 设置 var B 你会怎么做 var B if A red hot else cool 我认为这行不通 我想你可以做 if A red var B hot else var B
  • 四舍五入双打 - .5 - sprintf

    我使用以下代码四舍五入到 2dp sprintf temp 2f coef i coef i returns a double 成功将 6 666 舍入为 6 67 但舍入时无法正常工作 5 555 它返回 5 55 而它应该 至少在我看来
  • 是否有必要将动态数组的容量加倍?

    当在 C 中创建自动扩展数组 如 C 的 std vector 时 通常 或者至少是常见的建议 在每次填充时将数组的大小加倍 以限制调用的数量realloc为了尽可能避免复制整个数组 例如 我们首先为 8 个元素分配空间 插入 8 个元素