I use boost :: make_shared to create objects that are shared by pointers. Mainly because our code was too slow, and one distribution really helped improve performance.
After fixing the memory leaks, the “hard manual way”, I decided to implement a simple memory leak detector, redefining the new operators for all the corresponding classes only to count which objects are still alive at certain points in our application. I implemented this several times earlier and was surprised to find that my code no longer detects any objects.
I realized that all I had to do was to redefine the "placement of new" instead of the "normal" new operator due to the following from the boost website documentation for make_shared:
"Effects: allocates memory suitable for an object of type T and creates an object in it through a new expression new (pv) T () or new (pv) T (std :: forward (args) ...) . Allocate_shared uses a copy of a for memory allocation. If an exception is thrown, the effect. "
My new placement is also not called. I wrote 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 makes the following conclusion:
... Global new Test::Test() ... Test new Test::Test() Global new ...
I was expecting "Test non-throwing placement new" on the third line of output. What do you think should be the behavior? Do you agree that, according to the documentation of make_shared, it should name the new placement operator of my class Test? Or didn’t I understand this?
I could copy the implementation implementation locally and, of course, add a call to the new placement operator. But would this be appropriate or would violate the alleged semantics of placing new?
Thanks in advance for your time and your help.