c++11 - c++ std::make_shared with new macro -
i use macro in place of new
information in debug mode:
#if defined(_debug) #define sage_new new(__function__, __file__, __line__) #else #define sage_new new #endif
i have found quite useful in custom memory profiling , memory leak detection. started using shared pointers, making heap objects like:
auto mythingy = std::shared_ptr<thingy>(sage_new thingy(args) );
i have learned std::make_shared
preferred because uses fewer memory allocations. there way can include sage_new
in make_shared
? realize won't matter leak detection still memory usage statistics. seems allocate_shared
somehow holds answer haven't figured out. thanks! :)
edit : asking new
- overload custom new
. compiler option sage_mem_info turns on leak detection , memory usage stats, otherwise skips logging , goes directly memory pool allocation. have new[] , delete[] variants i'm omitting brevity:
#ifdef sage_mem_info void* operator new (size_t size){ ++appallocs; return myalloc(size); } void* operator new (size_t size, char const *function, char const *filename, int linenum) { ... log memory usage void* ptr = ::operator new(size); return ptr; } void operator delete (void* ptr) { ... log freeing of pointer --appallocs; myfree(ptr); } void operator delete (void* ptr, char const *function, char const *filename, int linenum) { ... log freeing of pointer --appallocs; myfree(ptr); } #else void* operator new (size_t size){ return myalloc(size); } void* operator new (size_t size, char const *function, char const *filename, int linenum) { void* ptr = ::operator new(size); return ptr; } void operator delete (void* ptr) { myfree(ptr); } void operator delete (void* ptr, char const *function, char const *filename, int linenum) { myfree(ptr); } #endif
yes, can so.
still, have choose poison:
- use allocator-type not empty, saves @ least pointer.
- use new allocator-type each allocation, reflected in new polymorphic type reference-count.
http://en.cppreference.com/w/cpp/concept/allocator shows requirements, , minimal allocator declaration.
adapted std::allocator
here first option:
#if defined(_debug) template <class tp> struct debuglinesallocator : std::allocator<tp> { const char* func, *file; int line; tp* allocate(std::size_t n, const void* = 0) {return ::operator new(n * sizeof(t), func, file, line);} template< class u > struct rebind { typedef debuglinesallocator<u> other; }; debuglinesallocator(const char* func, const char* file, int line) : func(func), file(file), line(line) {} template< class u > debuglinesallocator( const debuglinesallocator<u>& other ) : func(other->func), file(other->file), line(other->line) {} }; #define sage_make_shared(type, ...) allocate_shared<type>(debuglinesallocator<type>\ {__function__, __file__, __line__}, __va_args__) #else #define sage_make_shared(type, ...) make_shared<type>(__va_args__) #endif
still, far less useful shared-pointers. anyway, every little bit may help.
use like
auto p = sage_make_shared(my_type, my_argument_1, ...);
Comments
Post a Comment