C++ operator new[]和Debug Heap

本文探讨了在Visual Studio 2005中使用CRTDebugHeap进行内存泄漏检测的方法,并详细分析了operator new[] 和 malloc 在调试堆上的表现差异,提供了解决方案以准确地定位内存泄漏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ operator new[]和Debug Heap

原贴地址:
http://eparg.spaces.live.com/blog/cns!59BFC22C0E7E1A76!1490.entry
原贴时间:
2006-08-15
原贴作者:
eparg

如果在VS2005下面想用CRT Debug Heap来调试Memory Leak,最后可以用_CrtDumpMemoryLeaks 把所有的leak打印出来。尝试下面的代码,会怎样:

#include "stdafx.h"

#ifdef _DEBUG

#define _CRTDBG_MAP_ALLOC

#include<stdlib.h>

#include<crtdbg.h>

#endif

#define MY_NEW[s] new(s,_NORMAL_BLOCK, __FILE__, __LINE__)

#if defined(_DEBUG) && defined(_CRTDBG_MAP_ALLOC)

#define new MY_NEW

#endif

int _tmain(int argc, _TCHAR* argv[])

{

char *p=new char[10];

void *p2=malloc(10);

#ifdef _DEBUG

_CrtDumpMemoryLeaks();

#endif

return 0;

}

运行后会看到:

Detected memory leaks!

Dumping objects ->

c:/documents and settings/lixiong/my documents/mycode/detectleak/detectleak/detectleak.cpp(17) : {87} normal block at 0x003A8130, 10 bytes long.

Data: < > CD CD CD CD CD CD CD CD CD CD

c:/program files/microsoft visual studio 8/vc/include/crtdbg.h(1150) : {86} normal block at 0x003A3240, 10 bytes long.

Data: < > CD CD CD CD CD CD CD CD CD CD

Object dump complete.

The program '[808] DetectLeak.exe: Native' has exited with code 0 (0x0).

注意这里打印出的第一个leak,出现在detectleak.cpp17行,对应的是malloc语句,没问题

可是第二个leak,出现在crtdbg.h1150行,而不是new char[10]那里,怎么回事?如果不能定位到正确的源代码,还有什么用呢?

为了搞清楚这个问题,可以看看mallocdebug heap下的的定义:

#ifdef _CRTDBG_MAP_ALLOC

#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)

注意看,这里用了__FILE__, __LINE__两个预处理器Directive:

The #line Directive
http://msdn2.microsoft.com/en-us/library/b5w2czay.aspx

由于与处理器自动把文件名和行号传递给了_malloc_dbg函数,最后的output窗口才可以打印出源代码行

那好,看看debug heapnew的定义。由于newC++的关键字,而且是一个操作符,所以debug heap下定义为:

inline __bcount(_Size) void* __CRTDECL operator new[](size_t _Size)

{ return ::operator new[](_Size, _NORMAL_BLOCK, __FILE__, __LINE__); }

注意这里没有用#define,而是inline。同时该定义是在crtdbg.h文件中的。所以最后得到的是文件名是crtdbg.h。你可能有如下疑问:

1. 为什么不用#define而要用inline呢,改成#define可以吗?
你试试看吧,看能不能该成#define。由于这里有一个中括号,麻烦来了吧。谁让你是C++呢?bs一下C++

2. 为什么预处理器看到inline函数,不把inline后的行号和文件名字作为解释呢?
这我就不确定了啦。不过根据C++标准,标示为inline函数不是一定就要inline的,人家标准就定义得模棱两可,你何必强求预处理器呢?

所以,解决方法就是,所有的内存分配,就用:

#ifdef _CRTDBG_MAP_ALLOC

char *test=(char*)::operator new[](20, _NORMAL_BLOCK, __FILE__, __LINE__);

#else

char *test=new char[20];

#endif

你有其它好方法吗?

 
### PyCharm 打开文件显示全的解决方案 当遇到PyCharm打开文件显示全的情况时,可以尝试以下几种方法来解决问题。 #### 方法一:清理缓存并重启IDE 有时IDE内部缓存可能导致文件加载异常。通过清除缓存再启动程序能够有效改善此状况。具体操作路径为`File -> Invalidate Caches / Restart...`,之后按照提示完成相应动作即可[^1]。 #### 方法二:调整编辑器字体设置 如果是因为字体原因造成的内容显示问题,则可以通过修改编辑区内的文字样式来进行修复。进入`Settings/Preferences | Editor | Font`选项卡内更改合适的字号大小以及启用抗锯齿功能等参数配置[^2]。 #### 方法三:检查项目结构配置 对于某些特定场景下的源码视图缺失现象,可能是由于当前工作空间未能正确识别全部模块所引起。此时应该核查Project Structure的Content Roots设定项是否涵盖了整个工程根目录;必要时可手动添加遗漏部分,并保存变更生效[^3]。 ```python # 示例代码用于展示如何获取当前项目的根路径,在实际应用中可根据需求调用该函数辅助排查问题 import os def get_project_root(): current_file = os.path.abspath(__file__) project_dir = os.path.dirname(current_file) while not os.path.exists(os.path.join(project_dir, '.idea')): parent_dir = os.path.dirname(project_dir) if parent_dir == project_dir: break project_dir = parent_dir return project_dir print(f"Current Project Root Directory is {get_project_root()}") ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值