我第一次使用 boost::make_shared 来创建共享指针指向的对象。主要是因为我们的代码太慢了,单次分配确实有助于 boost 性能。
在以“硬手动方式”修复了一些内存泄漏之后,我决定通过覆盖所有相关类的新运算符来实现一个简单的内存泄漏检测器,仅用于计算在我们的应用程序的特定点哪些对象仍然存在。我之前已经实现过几次,惊讶地发现我的代码不再检测到任何对象。
我认为我所要做的就是覆盖“placement new”而不是“normal”operator new,因为 make_shared 的 boost 网站文档中有以下内容:
"Effects: Allocates memory suitable for an object of type T and constructs an object in it via the placement new expression new( pv ) T() or new( pv ) T( std::forward(args)... ). allocate_shared uses a copy of a to allocate memory. If an exception is thrown, has no effect."
但是我的新展示位置也没有被调用。我编写了一个小测试程序来重现该行为:
#include <iostream>
using namespace std;
#include "boost/shared_ptr.hpp"
#include "boost/make_shared.hpp"
class Test
{
public:
Test() { cout << "Test::Test()" << endl; }
void* operator new (std::size_t size) throw (std::bad_alloc) {
cout << "Test new" << endl;
return malloc(size);
}
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw() {
cout << "Test non-throwing new" << endl;
return malloc(size);
}
void* operator new (std::size_t size, void* ptr) throw() {
cout << "Test non-throwing placement new" << endl;
return malloc(size);
}
};
void* operator new (std::size_t size) throw (std::bad_alloc) {
cout << "Global new" << endl;
return malloc(size);
}
int main() {
cout << "..." << endl;
boost::shared_ptr<Test> t1(boost::make_shared<Test>());
cout << "..." << endl;
boost::shared_ptr<Test> t2(new Test());
cout << "..." << endl;
return 0;
}
呈现以下输出:
...
Global new
Test::Test()
...
Test new
Test::Test()
Global new
...
我期待在输出的第 3 行出现“Test non-throwing placement new”。你认为行为应该是怎样的?您是否同意根据 make_shared 的文档,它应该调用我的测试类的 placement new 运算符?还是我误会了?
当然,我可以在本地复制 boosts 实现并添加对 placement new 运算符的调用。但是,这是否合适,或者是否会违反 placement new 的预期语义?
提前感谢您的宝贵时间和帮助。
最佳答案
作为make_shared 的来源,它使用全局放置new 运算符,而不是您的类提供的new 运算符。
::new( pv ) T();
不幸的是(至少在 OS X 上是这样) ( according to the standard ),您不能定义自己的全局布局新运算符。看来 allocate_shared更符合您正在寻找的内容。
编辑:
另一种方法是实际编写一个 make_shared 版本,它使用类的新位置而不是全局位置。它只有大约 10 行代码,只要您遵守 the license of the original code 就应该没问题.
关于c++ - boost::make_shared 不是在调用(放置)运算符 new 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9675225/
这似乎应该有一个直截了当的答案,但在Google上花了很多时间,所以我找不到它。这可能是缺少正确关键字的情况。在我的RoR应用程序中,我有几个模型共享一种特定类型的字符串属性,该属性具有特殊验证和其他功能。我能想到的最接近的类似示例是表示URL的字符串。这会导致模型中出现大量重复(甚至单元测试中会出现更多重复),但我不确定如何让它更DRY。我能想到几个可能的方向...按照“validates_url_format_of”插件,但这只会让验证干给这个特殊的字符串它自己的模型,但这看起来很像重溶液为这个特殊的字符串创建一个ruby类,但是我如何得到ActiveRecord关联这个类模型
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak
我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m
请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是
我有一张背景图片,我想在其中添加一个文本框。我想弄清楚如何将标题放置在其顶部的正确位置。(我使用标题是因为我需要自动换行功能)。现在,我只能让文本显示在左上角,但我需要能够手动定位它的开始位置。require'RMagick'require'Pry'includeMagicktext="Loremipsumdolorsitamet"img=ImageList.new('template001.jpg')img 最佳答案 这是使用convert的ImageMagick命令行的答案。如果你想在Rmagick中使用这个方法,你必须自己移植
我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent