boost :: make_shared不是调用(placement)运算符new? [英] boost::make_shared is not calling (placement) operator new?

查看:419
本文介绍了boost :: make_shared不是调用(placement)运算符new?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我第一次使用boost :: make_shared创建共享指针指向的对象。主要是因为我们的代码太慢,单个分配真的有助于提高性能。

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.

修复一些内存泄漏硬手动方式后,我决定实现一个简单的内存泄漏检测器通过覆盖所有相关类的新运算符,只是为了计数哪些对象仍然活在我们的应用程序中的特定点。我已经实现了几次之前,并惊讶地发现我的代码不再检测到任何对象。

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.

我想我所要做的就是重写placement new的正常运算符new的,因为以下来自boost网站文档的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:


效果:分配适合对象的内存的类型T
通过放置新表达式new(pv)
T()或new(pv)T(std :: forward(args))构造一个对象。 ..)
。allocate_shared
使用a的副本来分配内存。如果抛出异常,没有
的效果。

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

我的展示位置new也不会被调用。我写了一个小测试程序来重现行为:

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

这会生成以下输出:

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



期望测试非抛弃式放置新在第三行输出。你认为行为应该是什么?你同意根据make_shared的文档,它应该调用我的测试类的placement新操作符?还是我误会了?

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?

我可以在本地复制boost实现,并向placement new操作符添加一个调用。

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 的来源,它使用全局放置 new 运算符,而不是您的类提供的新运算符。

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 的版本,它使用类的布局new而不是全局布局。它只有大约10行代码,只要您符合原始代码的许可证

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.

这篇关于boost :: make_shared不是调用(placement)运算符new?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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