gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:08:53 24 4
gpt4 key购买 nike

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

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com