最近遇到的内存问题比较严重,测试下来win32的程序在32机上最多可以分配出2G的内存,就会bad_alloc掉了。
下面是整理的一些查找内存使用的代码。
#include <iostream>
struct aaa
{
int xxx;
float yyy;
char zzz;
};
#define CLIENTBLOCK new(__FILE__, __LINE__)
#define NEW CLIENTBLOCK
void *operator new(size_t size,char *file,int line)
{
std::cout << "[" << size << "]--" << file << "("<<line << ")" << std::endl;;
return ::operator new(size);
}
int main()
{
int *pInt = NEW int(10);
aaa* wode = NEW aaa;
system("pause");
delete pInt;
return 0;
}
重载了new,用于打印出来每次分配的大小,NEW的文件&行号
之后我们可以再做分析。
#include <iostream>
int MyAllocHook( int nAllocType, void *pvData, size_t nSize, int nBlockUse, long lRequest, const unsigned char * szFileName, int nLine )
{
//_CRT_BLOCK 块是由 C 运行时库函数内部进行的内存分配,必须显式地忽略
if( nBlockUse == _CRT_BLOCK )
return true;
if( nAllocType == _HOOK_ALLOC )
{
printf("分配内存 大小:%d; 文件:%s; 行号:%d\n", nSize, szFileName, nLine );
}
else if( nAllocType == _HOOK_REALLOC )
{
printf("重分配内存 大小:%d; 文件:%s; 行号:%d\n", nSize, szFileName, nLine );
}
else if( nAllocType == _HOOK_FREE )
{
printf("释放内存 大小:%d; 文件:%s; 行号:%d\n", nSize, szFileName, nLine );
}
return true;
}
#ifdef new
#undef new
#endif
#define NEW new(_NORMAL_BLOCK, __FILE__, __LINE__ )
#ifdef delete
#undef delete
#endif
#define DELETE delete/*(__FILE__, __LINE__)*/
struct aaa
{
int xxx;
float yyy;
char zzz;
};
int main()
{
_CrtSetAllocHook(MyAllocHook);
int *pInt = NEW int(10);
aaa* wode = NEW aaa;
DELETE pInt;
DELETE wode;
return 0;
}
这段代码是用钩子的方式,不过感觉不是很好,服务器还没有启动完成就挂掉了,应该是MyAllocHook printf的问题。上面重载的delete不好用。
内存问题最严重的是内存泄露&野指针。虽然现在很多人使用内存池,不过还是觉得内存碎片是不可避免的,在一定范围内是可接受的。
有很多检测内存泄露的工具,不过检测结果都不理想。大部分应该都是基于_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );的