gpt4 book ai didi

c++ - 使用 typeinfo::name() 后内存泄漏

转载 作者:可可西里 更新时间:2023-11-01 17:42:27 33 4
gpt4 key购买 nike

我有一个程序,其中部分用于信息日志记录,我在使用时输出一些类的名称(具体来说,我在日志中添加了一个条目,上面写着 Messages::CSomeClass transmitted to 127.0 .0.1)。我使用类似于以下的代码执行此操作:

std::string getMessageName(void) const {
return std::string(typeid(*this).name());
}

是的,在有人指出之前,我意识到 typeinfo::name 的输出是特定于实现的。

根据 MSDN

The type_info::name member function returns a const char* to a null-terminated string representing the human-readable name of the type. The memory pointed to is cached and should never be directly deallocated.

但是,当我在调试器中退出我的程序时,typeinfo::name() 的任何"new"使用都会显示为内存泄漏。如果我输出 2 个类的信息,我会得到 2 个内存泄漏,依此类推。这暗示缓存数据永远不会被释放。

虽然这不是主要问题,但它看起来很乱,经过长时间的调试 session 后,它很容易隐藏真正的内存泄漏。

我环顾四周,发现了一些有用的信息(一个 SO 答案提供了一些关于 how typeinfo may be implemented 的有趣信息),但我想知道这个内存是否通常应该由系统释放,或者我是否可以做些什么在调试时“不注意”泄漏。

我确实有一个后备计划,就是自己编写 getMessageName 方法而不依赖于 typeinfo::name,但我想知道不管怎样,如果我遗漏了什么。

最佳答案

另一种解决方案是纠正根本问题。这并不是真正的内存泄漏,只是一个错误的报告。分配给 tyepinfo() 和 name() 字符串的内存块分配了错误的 block 类型。 “释放”这个内存可能不是一个好主意,因为 CRT 会尝试再次释放它。好消息是这最终在 VS2012 (_MSC_VER 1700+) 中得到修复。

由于这仅适用于 _DEBUG 构建,以下可能是更安全的解决方案。应该在退出模块入口点(main、WinMain 等)之前调用函数 _FixTypeInfoBlockUse()。

#if defined(_DEBUG) && (_MSC_VER >= 1000 && _MSC_VER <= 1699)
//
// Debug memory block header:
// o Borrowed from the Microsoft CRT to fix the false "memory leak" report
// when using typeinfo 'name' accessor in a _DEBUG build of the library.
//
struct _CrtMemBlockHeader
{
struct _CrtMemBlockHeader * pBlockHeaderNext;
struct _CrtMemBlockHeader * pBlockHeaderPrev;
char * szFileName;
int nLine;
#ifdef _WIN64
int nBlockUse;
size_t nDataSize;
#else
size_t nDataSize;
int nBlockUse;
#endif
long lRequest;
unsigned char gap[4];
};

static void __cdecl _FixTypeInfoBlockUse(void)
{
__type_info_node* pNode = __type_info_root_node._Next;

while(pNode != NULL)
{
__type_info_node* pNext = pNode->_Next;

(((_CrtMemBlockHeader*)pNode) - 1)->nBlockUse = _CRT_BLOCK;

if (pNode->_MemPtr != NULL)
(((_CrtMemBlockHeader*)pNode->_MemPtr) - 1)->nBlockUse = _CRT_BLOCK;

pNode = pNext;
}
}

#endif//defined(_DEBUG) && (_MSC_VER >= 1000 && _MSC_VER <= 1699)

关于c++ - 使用 typeinfo::name() 后内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8308671/

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