这是我在学生时代问自己的一个问题,但没有得到满意的答案,我一点一点地想出来......直到今天。
我知道我可以通过检查返回的指针是否为 NULL 或通过处理 bad_alloc 异常来处理分配内存错误。
好的,但我想知道:new 的调用如何以及为什么会失败?据我所知,如果空闲存储中没有足够的空间,分配内存可能会失败。但是现在这种情况真的会发生吗,有几 GB 的 RAM(至少在普通计算机上;我不是在谈论嵌入式系统)?我们是否还有其他可能发生分配内存失败的情况?
最佳答案
虽然您已经获得了许多关于内存可能失败的原因/方式的答案,但其中大多数都忽略了现实。
实际上,在真实系统上,这些论点中的大多数都没有描述事物的真正运作方式。尽管从这些是尝试内存分配可能失败的原因的角度来看,他们是正确的,但从描述事物在现实中通常如何工作的角度来看,他们大多是错误的。
例如,在 Linux 中,如果您尝试分配比系统可用的内存更多的内存,您的分配将不会失败(即,您不会得到空指针或 strd: :bad_alloc 异常)。相反,系统将“过度提交”,因此您会得到看似有效的指针——但是当/如果您尝试使用所有内存时,您将收到异常和/或 OOM Killer将运行,试图通过杀死使用大量内存的进程来释放内存。不幸的是,这可能与其他程序一样容易杀死发出请求的程序(事实上,许多试图通过重复分配大块内存来导致分配失败的示例应该是最先被杀死的)。
Windows 的工作方式有点更接近 C 和 C++ 标准的设想方式(但只有一点点)。 Windows 通常配置为在必要时扩展交换文件以满足内存分配请求。这意味着当您分配更多内存时,系统会因为交换内存而变得半疯狂,创建越来越大的交换文件以满足您的要求。
这最终会失败,但在具有大量驱动器空间的系统上,它可能会在此之前运行 小时(其中大部分是在磁盘上疯狂地移动数据)。至少在用户实际使用的典型客户端计算机上......好吧,使用计算机时,他会注意到一切都已经停止,并在分配失败之前采取措施阻止它。
因此,要获得真正失败的内存分配,您通常会寻找其他而不是典型的台式机。一些例子包括一台服务器在无人值守的情况下一次运行数周,并且负载非常轻,以至于没有人注意到它连续 12 个小时在磁盘上颠簸,或者一台运行 MS-DOS 或某些 RTOS 的机器不提供虚拟内存。
底线:你基本上是对的,而他们基本上是错的。虽然如果您分配的内存比机器支持的多,这是肯定的,但通常不失败必然会以 C++ 标准规定的方式发生 - 而且,事实上,对于典型的台式机来说,这更多的是异常(exception)(请原谅双关语)而不是规则。
关于c++ - 分配内存如何以及为什么会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18684951/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%