If you feel the need for realloc() - and many do - then consider using a standard library vector.
我会通过同意 std::vector 更好来作为我的问题的开头,原因有很多,而且我个人总是会选择使用它而不是使用 C 内存分配编写我自己的动态数组。
但是,std::vector 会在内存增长时产生碎片,因为 C++ 没有等效的 realloc(编辑 澄清一下,我知道 std::vector 的存储是连续的,不会碎片化,我的意思是分配和解除分配导致的内存空间碎片,realloc 可以通过扩展现有分配来避免)。那么总是推荐它而不是 realloc 公平吗?非常小心,你不能写一些像 std::vector 但使用 C 分配函数的东西,它有可能在不移动它的地址和复制现有元素的情况下增加它的内存,使它在碎片化和性能方面一样好还是更好?
与此相关(奖金问题!),为什么 C++ 没有与realloc 等效的东西?在如此注重性能的语言中省略似乎是一件奇怪的事情。 Bjarne 的常见问题解答中的部分正是这个标题(减去强调),但答案没有解决“为什么”。这只是一个偶然的遗漏吗? new/delete 的工作方式是否存在一些根本性的不兼容?它在实践中并没有真正带来看起来的好处吗?
编辑:好的,所以我忽略了考虑 realloc 的 C 肮脏 - std::vector 不能使用重写realloc 因为它只适用于 POD,不会抛出等等。也许在某些情况下,编写一个 POD-only 容器来处理这些问题是个好主意。不过无论如何,更有趣的问题变成了:std::vector 是否会受益于 realloc 的 C++ 等价物,这里(或多或少)已经回答了这个问题:
Does std::vector *have* to move objects when growing capacity? Or, can allocators "reallocate"?
遗憾的是,答案似乎是“是的,但标准委员会没有投票通过”。希望如此。
最佳答案
new/new[]和 delete/delete[]通常在 C 库分配函数(ala malloc/realloc/free )之上分层,可能还有一个额外的层用于使用一个 malloc 的小对象优化。 -ed 区域快速满足许多小 new要求。这种分层意味着支持 new和 delete早期 C++ 库作者只需要很少的实现工作。
利用 realloc 中的就地调整大小功能但是,对于 C++,对 realloc 的侵入性更改需要库函数,这样如果需要移动到新的内存区域,C++ 库代码就有机会复制构造/破坏正在移动的对象。这可以这样做:
回调发生在 realloc 之后意识到移动是必要的,要求 C++ 库执行实际的数据移动而不是执行 memcpy()样式按字节复制,或
作为一个额外的就地调整大小或失败而不移动的函数,因此 C++ 库代码可以尝试它,然后返回到 malloc在删除原始对象和释放原始内存之前进行适当/安全的复制。
作为大多数 C 库 realloc函数缺少任何此类 Hook /查询工具,C++ 标准和标准库不需要它。正如 Mehrdad 指出的那样,this answer记录 SGI 对这个问题的确认。
考虑到如今 C++ 的广泛使用,恕我直言,发布一个 malloc 是有意义的/realloc/free C++ 库本身的实现确实提供了这样的钩子(Hook)/查询,因此在 realloc 中看到实用程序的 C++ 库作者可以自由使用;那将是一个值得包含在未来标准中的候选者。
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?
如上所述 - 不 - 在不更改 realloc 的情况下,不可能非常小心地复制构造/破坏对象。 API。
关于c++ - 总是推荐 std::vector 而不是 realloc 公平吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22932984/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd
我想为我的Rails网络应用程序提供推荐功能。特别是,我想向新注册的用户推荐他可能想要关注的其他用户。Rails中是否有用于此目的的引擎/gem?如果没有,我应该从哪里开始构建它?谢谢。 最佳答案 有Coletivogemhttps://github.com/diogenes/coletivo我试了一下。在MySQL上运行。Neo4jhttp://neo4j.org真的很容易实现一个“跟随谁”。事实上,大多数展示其能力的样本都涉及“跟随谁”。快速提示-只有在JRuby上运行时,Neo4j.rb才会很酷。如果不是-使用Neograph
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
您将如何构建一个简单的Sinatra应用程序?我正在制作,我希望该应用具有以下功能:“应用程序”更像是一个包含所有信息的管理仪表板。然后另一个应用程序将通过REST访问信息。我还没有创建仪表板,只是从数据库中获取东西session和身份验证(尚未实现)您可以上传图片,其他应用可以显示这些图片我已经使用RSpec创建了一个测试文件通过Prawn生成报告目前的设置是这样的:app.rbtest_app.rb因为我实际上只有应用程序和测试文件。到目前为止,我已经将Datamapper用于ORM,将SQLite用于数据库。这是我的第一个Ruby/Sinatra项目,所以欢迎任何和所有建议-我应
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
如果names为nil,则以下中断。我怎样才能让这个map只有在它不是nil时才执行?self.topics=names.split(",").mapdo|n|Topic.where(name:n.strip).first_or_create!end 最佳答案 其他几个选项:选项1(在其上执行map时检查split的结果):names_list=names.try(:split,",")self.topics=names_list.mapdo|n|Topic.where(name:n.strip).first_or_create!e
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“