c++ - boost::make_shared 不是在调用(放置)运算符 new 吗?

标签 c++ boost new-operator make-shared

我第一次使用 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/

相关文章:

javascript - 打开一个新窗口,其中包含帖子值增强功能

c++ - 为什么 new 不需要转换为指针,即使 malloc 需要它?

java - 调用构造函数时嵌套几个新的运算符是不是错了?

c++ - 为什么我不能在 C++ 的 setter 中这样设置?

c++ - 链接器找不到函数定义,LNK2001 未解析的外部符号

c++ - 从 boost::ptr_vector 获取指针而不是引用

c++ - 使用 boost::container 或 boost::recursive_wrapper 创建不完整类型的容器

c++ - Wordcount C++ Hadoop 管道不起作用

c++ - 使用动态内存分配重载 istream 运算符

c++ - 如何使用 boost::filesystem "normalize"路径名?