提高:: make_shared不调用(安置)运营商新的? [英] boost::make_shared is not calling (placement) operator new?

查看:204
本文介绍了提高:: make_shared不调用(安置)运营商新的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用boost :: make_shared首次创建对象通过共享指针指向。这主要是因为我们的code太慢,单分配确实有助于提高性能。

I am using boost::make_shared for the first time to create objects pointed to by shared pointers. Mainly because our code was too slow and the single allocation really helped to improve performance.

修复一些内存泄漏硬手动方式后,我决定通过重写新的运营商所有相关的类只是为了计算这些对象仍然在我们的应用程序的特定点活来实现一个简单的内存泄漏检测器。我已经实现在此之前好几次,却惊讶地发现我的code不再检测到任何物体。

After fixing some memory leaks "the hard manual way" I decided to implement a simple memory leak detector by overriding new operators for all relevant classes just for counting which objects are still alive at specific points in our application. I have implemented this several times before and was surprised to find my code no longer detects any objects.

我想,我必须做的是超越的新布局,而不是正常运营商新的因为从提升网站的文档以下为make_shared:

I figured that all I had to do is override "placement new" instead of the "normal" operator new's because of the following from the boost website documentation for make_shared:

效果:分配内存适合类型的对象牛逼
  通过放置新的前pression新(PV)在它构造一个对象
  T()或新(PV)T(性病::前进(参数)...)
。 allocate_shared
  使用分配内存的副本。如果抛出一个异常,无
  效应。

"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."

我的新位置还没有被称为然而。我已经写了一个小的测试程序来重现问题:

My placement new is also not being called however. I have written a small test program to reproduce the behavior:

#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;
}

这使得下面的输出:

Which renders the following output:

...
Global new
Test::Test()
...
Test new
Test::Test()
Global new
...

我所期待的测试不抛出放置新的输出的第三行。你认为什么行为应该是什么?你是否同意按照make_shared文档,它应该叫我的测试类的安置新的运营商?还是我误会了?

I was expecting "Test non-throwing placement new" on the 3rd line of output. What do you think the behavior should be? Do you agree that according to documentation of make_shared it should call the placement new operator of my Test class? Or did I misunderstand it?

我可以在本地复制提升执行,并加入到课程的布置新运营商的电话。但是,那又是适当的,否则会违反配售预期的语义新的?

I could copy boosts implementation locally and add a call to the placement new operator of course. But, would that be appropriate, or would it violate the intended semantics of placement new?

在此先感谢您的时间和你的帮助。

Thanks in advance for your time and your help.

推荐答案

展望为 make_shared 的来源,它采用了全球布局新的运营商,而不是由你的类提供新的运营商。

Looking as the source of make_shared, it uses the global placement new operator, instead of the new operator supplied by your class.

::new( pv ) T();

不幸的是<击>(如至少在OS X)(根据标准 ),则不能定义自己的全球布局新的运营商。看来, allocate_shared 是沿着你在找什么线条更。

Unfortunately (as least on OS X) (according to the standard), you cannot define your own global placement new operator. It appears that allocate_shared is more along the lines of what you're looking for.

修改

另一种可能是实际编写一个版本 make_shared 的它使用了类的新位置,而不是全球性的。这是只有约10 code线,并且应该罚款,只要你尊重原来的许可证code

An alternative could be to actually write a version of make_shared which uses the class's placement new instead of the global one. It's only about 10 lines of code, and should be fine so long as you honor the license of the original code.

这篇关于提高:: make_shared不调用(安置)运营商新的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆