[英]c++ std::make_shared with new macro
I use a macro in place of new
to get some extra information in debug mode: 我用一个宏代替
new
来在调试模式下获取一些额外的信息:
#if defined(_DEBUG)
#define SAGE_NEW new(__FUNCTION__, __FILE__, __LINE__)
#else
#define SAGE_NEW new
#endif
I have found this quite useful in custom memory profiling and memory leak detection. 我发现这在自定义内存分析和内存泄漏检测中非常有用。 I just started using shared pointers, so now I am making heap objects like:
我刚开始使用共享指针,所以现在我正在创建堆对象,如:
auto myThingy = std::shared_ptr<Thingy>(SAGE_NEW Thingy(Args) );
I have just learned that std::make_shared
is preferred because it uses fewer memory allocations. 我刚刚了解到
std::make_shared
是首选,因为它使用较少的内存分配。 Is there any way I can include my SAGE_NEW
in make_shared
? 有什么方法可以将我的
SAGE_NEW
包含在make_shared
吗? I realize it won't matter for leak detection but I would still like it for memory usage statistics. 我意识到它对于泄漏检测无关紧要,但我仍然希望它用于内存使用统计。 It seems like
allocate_shared
somehow holds the answer but I haven't figured it out. 似乎
allocate_shared
以某种方式得到了答案,但我还没弄明白。 Thanks! 谢谢! :)
:)
Edit : To those asking about new
- I overload it with a custom new
. 编辑 :对于那些询问
new
- 我用自定义new
重载它。 A compiler option SAGE_MEM_INFO turns on leak detection and memory usage stats, otherwise it skips logging and goes directly to my memory pool allocation. 编译器选项SAGE_MEM_INFO打开泄漏检测和内存使用情况统计信息,否则会跳过日志记录并直接进入内存池分配。 I have new[] and delete[] variants but I'm omitting those for 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 this pointer
--appAllocs;
myFree(ptr);
}
void operator delete (void* ptr, char const *function, char const *filename, int lineNum)
{
... Log freeing of this 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, you can certainly do so. 是的,你当然可以这样做。
Still, you have to choose your poison: 不过,你必须选择你的毒药:
http://en.cppreference.com/w/cpp/concept/Allocator shows the requirements, and a good minimal allocator declaration. http://en.cppreference.com/w/cpp/concept/Allocator显示了要求,以及一个很好的最小分配器声明。
Adapted std::allocator
here for the first option: 在这里为第一个选项改编了
std::allocator
:
#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, its far less useful for shared-pointers. 尽管如此,它对共享指针的用处却远远不够。 Anyway, every little bit may help.
无论如何,每一点都可能有所帮助。
Use it like 像它一样使用它
auto p = SAGE_MAKE_SHARED(my_type, my_argument_1, ...);
您可以创建自己的makeShared
,在那里您可以执行所需的任何记录,然后您将调用真正的make_shared
。
Posting in answers rather than the question... 发布答案而不是问题......
My compiler didn't like some things in Deduplicator's answer. 我的编译器不喜欢Deduplicator的答案中的一些东西。 Below doesn't seem to be completely wrong:
下面似乎没有完全错误:
template <class Tp>
struct DebugLinesAllocator : std::allocator<Tp> {
char const * func;
char const * file;
int line;
DebugLinesAllocator(char const * aFunc, char const * aFile, const int aLine) : func(aFunc), file(aFile), line(aLine) {}
Tp* allocate(std::size_t n, const void* = 0)
{
return static_cast<Tp*> (::operator new(n * sizeof(Tp), func, file, line));
}
template< class U > struct rebind { typedef DebugLinesAllocator<U> other; };
template< class U > DebugLinesAllocator(const DebugLinesAllocator<U>& other)
: func(other.func), file(other.file), line(other.line) {}
};
#if defined(_DEBUG)
#define SAGE_MAKE_SHARED(type, ...) std::allocate_shared<type>(DebugLinesAllocator<type>(__FUNCTION__, __FILE__, __LINE__), __VA_ARGS__)
#else
#define SAGE_MAKE_SHARED(type, ...) std::make_shared<type>(__VA_ARGS__)
#endif
Please let me know if you think any of my changes are suspect. 如果您认为我的任何更改都是可疑的,请告诉我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.