周星星 之 Blog

关注 ASM/C/C++

  VC知识库BLOG :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 登录 ::
  126 随笔 :: 25 文章 :: 2604 评论 :: 9 Trackbacks
<2008年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

News

留言簿(45)

随笔分类

随笔档案

文章分类

文章档案

相册

相关链接

搜索

最新评论

  • 1. 自创
  • 中国人的习惯是吃完了饭再付帐;洋人的习惯是先付帐后吃饭。
    于是餐馆老板想出了一个办法:
        与国际接轨:吃饭前先把饭钱付了;
        适应中国国情:吃完饭后付一次帐。
    这样一顿饭就可以收两次钱了。
  • --周星星
  • 2. re: windows下最好的C++ IDE
  • # re: windows下最好的C++ IDE 2008-05-18 14:58 xuebuyu 
    我试了最简单的程序,譬如只有一个std::cout << ..., printf (...), 发现vc2005产生的debug版本不能在没有.net framework下运行,而release可以
    ---------------------------------------------------------------------------
    debug版本也不需要的,可能是因为manifest文件的问题
  • --joe
  • 3. re: VS2005/VS2008 中64位数据引起的一个严重bug
  •  将 *(__int64*)(str+1) = *(__int64*)(str+0); 分解为
    *(__int32*)(str+5) = *(__int32*)(str+4);
    *(__int32*)(str+1) = *(__int32*)(str+0);
    就OK了

    看来关于__int64的赋值,编译的代码要根据两个变量地址来决定分解为两个__int32的操作的顺序
  • --mslk
  • 4. re: 网摘
  • 可惜中国人但对于羊显凶兽相,而对于凶兽则显羊相,所以即使显着凶兽相,也还是卑怯的国民。这样下去,一定要完结的。
    --- 《鲁迅警世名言录》
  • --周星星
  • 5. re: windows下最好的C++ IDE
  • 我在VC6.0里装了ICC,能正常使用.之前类模板的局部特化现在能编译通过了.但是在类声明里对静态数据成员初始化还是编译不过啊??
  • --keke
  • 6. re: 网摘
  • --周星星
  • 7. 自创
  • 两兄弟A和B,特穷,大哥A每次都忍饥挨饿却把B喂饱。
    长大后A瘦得像根杆,风一吹就倒;B却发育得很好,连吹3天牛屄也不累。

    B:A那家伙就是基因不好,人品不好,好吃懒做……,所以我现在身强力壮,他却赢弱得很,满身是病,快挂了。拖我家后腿呀!
    A:如果不是当年我把吃的留给你,你小子能油光满面,脑满肠肥,而我能在发育期间饿得营养不良,现在快挂了吗?
    B:当年我吃了你多少,现在我10倍还给你,看你能不能变得和我一样强壮?
    A:<气死了>
  • --周星星
  • 8. 杨辉三角(随便写的,估计有更好的写法)
  • --周星星
  • 9. to allenm:
  • 谢谢大虾。

    “为什么用wubi安装而不是直接硬盘安装呢?”
    ------ 一来需要分区,有些麻烦;二来8.10有bug,硬盘安装时无法分区,google了一下,可行的方法有:
    a. 用光盘安装
    b. 把启动文件放另一块硬盘,或U盘上。(a的原理其实和这个一样)
    c. 到分区时,先反挂载ISO所在分区
  • --周星星
  • 10. re: ubuntu8.10安装记
  • 囧,刚才没有看完你的文章就发评论了,现在发现很多我说的你已经解决了,另外说明一下你貌似还没有解决的上GTALK和MSN的问题吧,用系统自带的pidgin就可以了,这两个都可以上的,另外QQ也可以上,如果不可以上的话你可以去腾讯官网下载DEB包。
  • --allenm
  • 11. re: ubuntu8.10安装记
  • 你是刚开始用Ubuntu吧,其实这个很好用的,只是刚开始的时候你还不太适应罢了,为什么用wubi安装而不是直接硬盘安装呢?可以装个双系统啊,而且Ubuntu带的grub会直接找到你的windows分区,启动的时候可以选择。因为cd盘容量比较小,所以带的简体中文语言实际上是不完全的,你现在也打不出中文吧,你可以在系统设置里面找到语言设置选项,选择简体中文,然后会提示你安装语言包,用系统自带的新力得更新工具就可以了。更新完后设置一下SCIM输入法就可以打出中文了。另外国内的比较好的源有cn99,这个据说速度比较快
  • --allenm
  • 12. Wicd
  • http://www.lirui.name/post/134.html
  • --周星星
  • 13. re: ubuntu8.10安装记
  • 阿帮兔的口碑还不错滴。
    只是安装后敲入gcc你会很失望。。。。
  • --HateMath
  • 14. re: ubuntu8.10安装记
  • 根据 http://tech.ddvip.com/2008-06/121290441645303.html 制得后的对比

  • --周星星
  • 15. re longinus:
  • 谢谢,现在终于成功了,不知不觉间我牙齿都咬出血了:)
  • --周星星
  • 16. re: ubuntu8.10安装记
  • 分区的问题我一个朋友也遇到了,当时也没解决,可能是硬盘驱动的问题

    不过他后来装opensuse了……
  • --longinus
  • 17. Intel之CMOV等价指令
  • --周星星
  • 18. re: 暂存
  • --周星星
  • 19. re: windows下最好的C++ IDE
  • 个人感觉作为C++程序员不要太拘泥于工具,还是专注一下语言本身的东西,而且我根据自身的项目经验,发现很多企业都逐渐开始跨平台的开发,可见跨平台是大势所趋,所以对自身的发展还是专注对语言本身和各种跨平台标准库的学习和使用。
  • --Wing
  • 20. 顺便问问LZ一个相关的问题
  • 如果一段代码里执行了很多循环
    foo()
    {
       for(i=0;...){}
       for(i=0;...){}
       ...
     }
    这时那种代码更合理呢? 偶个人感觉适合把int i;定义到循环外似乎更好些,不知对否?
  • --假骑士
  • 21. re: 再次随便说说,缓解一下看到此代码所带来的郁闷
  • 代码二的好处是循环后,变量temp就可以消失了。
    重复定义的问题,其实循环内,temp一直存在,不存在重复定义的问题。
    另,实测了一下,这两段代码在VC++6里面的时间效率基本一致。
  • --假骑士
  • 22. re: 编译期时立即数溢出
  • --100000
  • 23. re: 实时数据库的简介(初稿)
  • 杨,你好:

       能不能告知 PI软件的价格体系。
  • --Xian
  • 24. re: 疑难
  • 怎么做可以为众生带来最大的利益?
  • --向月
  • 25. re: 编译期时立即数溢出
  • 老大,你的这些问题,都是怎么发现的啊,是会程序的bug中吗,觉得你真牛B
  • --ricardo
  • 26. re: [zdd]的一道题
  • --jjnet
  • 27. re: 再次随便说说,缓解一下看到此代码所带来的郁闷
  • 其实这根本就没有意义,只是个人风格不同而已,对此我既不反对也不赞同星星的说法.

    例子:我喜欢将花摆在门边外面(左面),老婆喜欢把花摆在门边里面(右面).一好事之人,非要对此指指点点,一笑而置之不理!
  • --非法用户
  • 28. re: 佛学佳句
  • 南无阿弥陀佛!  ^_^
  • --meiko
  • 29. re: windows下最好的C++ IDE
  • 各位有听说过C-Free吗?国人的作品。

    我觉得还是很不错的,它能够支持很多种编译器,VC或者GCC等都可以。目前最新好像是4.0版.
  • --allen
  • 30. re jeffer:
  • :)避开VC的bug是一回事,VC有没有这个bug是另一回事。
  • --周星星
  • 31. re Dark:
  • your are right, thanks
  • --周星星
  • 32. re: VS2005/VS2008 中编译流程的一个严重bug
  • 试了一下,DEBUG方式编译是错了,但是Release编译倒是正确的
  • --Dark
  • 33. re: **
  • --jeffer
  • 34. re jeffer:
  • 每个人第一眼看到这代码自然会如你这样想,我一开始也认为是“未定义”行为。
    不过仔细对比一下,*(__int64*)(str+0) 对operator= 而言是个值,因此根本不存在所谓的重叠。

    如果不想被*(__int64*)(str+0)迷住了眼,那么写成
    __int64 tmp = *(__int64*)(str+0);
    *(__int64*)(str+1) = tmp;
    在VS200X的release下同样输出错误数据。
  • --周星星
  • 35. re: VS2005/VS2008 中64位数据引起的一个严重bug
  • 精典的搬石頭砸到自己 , 當來源和目標重叠.
    不能稱為bug, 這算是 沒定義, 寫碼自己要避免
    就好比
       memcpy( src , src+4 , 5);
       memcpy( src+4 , src , 5);
  • --jeffer
  • 36. 给ms发一个bug report吧
  • rt
  • --局部变量
  • 37. 求M数中取N数的排列组合
  • --周星星
  • 38. re: 计算24点的小程序(更新版)
  • 您好,我想请问一下24点的算法原理。是否能详细讲解一下,谢谢!
  • --妮妮
  • 39. re: 网摘
  • 1956年12月18日,国务院曾发出《关于今后在行文中和书报杂志里一律不用“满清”的称谓的通知》。通知原文如下:

    “满清”这个名词是在清朝末年中国人民反对当时封建统治者这一段历史遗留下来的称谓。在目前我国各民族已经团结成为一个自由平等的民族大家庭的情况下,如果继续使用,可能使满族人民在情绪上引起不愉快的感觉。为了增进各民族间的团结,今后各级国家机关、学校、企业,各民主党派,各人民团体,在各种文件、著作和报纸、刊物中,除了引用历史文献不便改动外,一律不要用“满清”这个名称。(见1986年南京大学出版社出版的《统一战线工作手册》)
  • --周星星
  • 40. re: gcc/mingw/libstdc简介
  • 非常之谢谢。。。
  • --以函
  • 41. szj 求助GDI+
  • Image image( L"D:\\boy3.jpg" );
    参数用CString strFilePath来代替怎么写
  • --szj
  • 42. re: [zdd]的一道题
  • 我觉得并不是return造成的。return的时候有一个析构是正常的。多出来的析构是在参数传递的时候多出来的。
    我猜想,没有copy constructor的时候

    foo(A()) 等价于 A a; foo(a);
  • --Justin Shen
  • 43. re: 取浮点数的整数部分(确实有点无聊,不喜欢就召回删除)
  • double a = 6.7f;
    double b = a * 10;
    int c = a * 10;
    int d = b;

    printf( "%d", c ); // 输出 67
    printf( "%d", d ); // 输出 66

    如果是double的刚好相反也。
  • --re: 取浮点数的整数部分
  • 44. re: 实时数据库的简介(初稿)
  • 谁有WPKS安装说明?
  • --YangJun
  • 45. 这鸡蛋真难吃
  • --周星星
  • 46. re: VS2005/VS2008 的一个严重bug
  • defined _CHAR_UNSIGNED
    255
    0
    char_max = 255
    char_min = 0

    为什么我的 VS2008 没有?

  • --Orez
  • 47. re: VS2005/VS2008 的一个严重bug
  • 但愿微软加油了
  • --REgicide
  • 48. re: VS2005/VS2008 的一个严重bug
  • 哦,确实是MS的严重BUG
  • --100000
  • 49. re: VS2005/VS2008 的一个严重bug
  • 不会吧,这都能错
  • --gaoqing000
  • 50. re: time_t 和 DATE 之间的相互转化
  • --yqever
  • 51. re: time_t 和 DATE 之间的相互转化
  • 嘿嘿,多谢。
    收藏了。
  • --yqever
  • 52. 判断strtoull是否溢出,errno=0是必要的
  • --周星星
  • 53. re: VS2005/VS2008 的一个严重bug
  • defined _CHAR_UNSIGNED
    255
    0
    char_max = 127
    char_min = 128


    visual studio 2008 sp1 居然还是这样的.
  • --test
  • 54. re: VS&G++ 重载operator delete的bug
  • 当不同堆栈,delete 一个 void* 进不了 Destructor
    如果操作是在 堆A里 new ,到堆 B 里 delete。
    那么 
    void operator delete( void* raw )
    。。。
    delete( (foo*)raw ); 
    delete( (int*)raw );   或者
    delete( (typename T*)raw );  模板 
  • --布伦特
  • 55. re pcasa:
  • 正常是正常了,可它完全不对了呀:)
    new operator 包含 operator new 和 construct
    delete operator 包含 destruct 和 operator delete
  • --周星星
  • 56. re: VS&G++ 重载operator delete的bug
  • --pcasa
  • 57. re: VS&G++ 重载operator delete的bug
  • this->operator new();

    MFC的做法是

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
  • --布伦特
  • 58. re: VC2005调试器的一个小小bug
  • 貌似long long 出了问题,如果用*(unsigned __int64*)&a就能正常显示
  • --zdd
  • 59. re: windows下最好的C++ IDE
  • 我是菜鸟,听说SlickEdit2008很好用支持30种以上的语言..包括C/VC++但是不知用什么编译器好?...周大哥可以帮我解答一下吗..谢谢
  • --hn2008
  • 60. 我不认为 ‘靠’来源于 Wacko
  • 因为 wacko 在英文中很少做语气词,语气词是放在口边的,与句子无关的。如 fuck, damn, my god, my,  shit, 等等。

    he is a wacko person,  he is so wacko.  

    ‘靠’在中文里是语气词。对不上。

    问下年龄大的人,都知道在 80年代并没广泛使用这个语气词,而都是用 ‘操’。

    所以我认为 ‘靠’是 ‘操’的文雅化的变种。
  • --路过二

阅读排行榜

评论排行榜

这篇文章是对2004-09-02日发表的《VC++6.0中简单的内存泄漏检测事例代码》(已经删除)的更新.

对C++代码而言,内存泄漏问题虽然有诸多方法避免,但实际代码编写的时候,或出于自信或出于复杂性的考虑,常常还会用到原始的operator new,这不可避免的会带来内存泄漏的可能,不久前本人因为违反了"可用于被多态继承的基类其析构函数应当有virtual修饰"的法则( 一不小心就忘了写virtual ^_^ ),导致了内存泄漏,因此我觉得出于安全考虑,在代码中加入内存泄漏检查机制还是很必要的,也因为这次的内存泄漏事件促使我写出这一篇文章.

VC++中本身就有内存泄漏检查的机制,你可以在向导生成的支持MFC的工程中看到如下代码:
  #ifdef _DEBUG
  #define new DEBUG_NEW
  #undef THIS_FILE
  static char THIS_FILE[] = __FILE__;
  #endif
通过它们,你能非常容易的发现代码中的内存泄漏,但是如果手工将这个功能移植到非MFC工程中去是很繁琐的一件事,另外它还有一个bug,在多线程并发调用这个DEBUG_NEW时会导致系统级错误,因此本人在此重写了这个功能,将以下的debug_new.h和debug_new.cpp添加到工程中,并在需要检测的cpp中#include "debug_new.h"和main中一开始处加入REG_DEBUG_NEW宏即可.

1. debug_new.h 源代码
/************************************************************************/
/* comment:  此文件与debug_new.cpp配合使用,用于在调试期发现内存泄漏     */
/*           仅在VC++编译器中适用(包括Intel C++,因为它使用了相同的库)   */
/* 作者:     周星星 http://blog.vckbase.com/bruceteen/                  */
/* 版权申明: 无,可任意 使用,修改 和 发布                                */
/************************************************************************/

/* sample

#include <iostream>
#include "debug_new.h" // +
using namespace std;

int main( void )
{
    REG_DEBUG_NEW; // +

    char* p = new char[2];

    cout << "--End--" << endl;
    return 0;
}

在VC++ IDE中按F5调试运行将会在Output窗口的Debug页看到类似如下的提示:
Dumping objects ->
d:\test.cpp(10) : {45} normal block at 0x003410C8, 2 bytes long.
Data: <  > CD CD
Object dump complete.

如果不出现如上提示请Rebuild All一次.

*/


#ifndef _DEBUG_NEW_H_
#define _DEBUG_NEW_H_

    #ifdef _DEBUG

        #undef new
        extern void _RegDebugNew( void );
        extern void* __cdecl operator new( size_t, const char*, int );
        extern void __cdecl operator delete( void*, const char*, int);
        #define new new(__FILE__, __LINE__)
        
        #define REG_DEBUG_NEW _RegDebugNew();

    #else

        #define REG_DEBUG_NEW

    #endif // _DEBUG

#endif // _DEBUG_NEW_H_


2. debug_new.cpp 源代码
/************************************************************************/
/* comment:  此文件与debug_new.h配合使用,用于在调试期发现内存泄漏       */
/*           仅在VC++编译器中适用(包括Intel C++,因为它使用了相同的库)   */
/* 作者:     周星星 http://blog.vckbase.com/bruceteen/                  */
/* 版权申明: 无,可任意 使用,修改 和 发布                                */
/************************************************************************/

//#include "debug_new.h"

#ifdef _DEBUG

#include <windows.h>
#include <crtdbg.h>

class _CriSec
{
    CRITICAL_SECTION criSection;
public:
    _CriSec()    { InitializeCriticalSection( &criSection ); }
    ~_CriSec()   { DeleteCriticalSection( &criSection );     }
    void Enter() { EnterCriticalSection( &criSection );      }
    void Leave() { LeaveCriticalSection( &criSection );      }
} _cs;

void _RegDebugNew( void )
{
    _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF );
}
void* __cdecl operator new( size_t nSize, const char* lpszFileName, int nLine )
{
    // comment 1: MFC中提供的debug new虽然加了锁,但我在实际测试的时候发现多线程并发
    //            调用的时候还是抛出了系统错误,所以我在这里加了一个线程互斥量.
    // comment 2: debug new和debug delete之间需不需要互斥我并不知道,保险起见,我同样
    //            加了线程互斥量.
    // comment 3: 按照C++标准规定,在operator new失败后应当调用set_new_handler设置的
    //            函数,但是MSDN中却说"头文件new中的set_new_handler是stub的,而应该使
    //            用头文件new.h中的_set_new_handler",这简直是滑天下之大稽.
    //            以下是VC++6.0中的set_new_handler定义:
    //                new_handler __cdecl set_new_handler( new_handler new_p )
    //                {
    //                    assert( new_p == 0 ); // cannot use stub to register a new handler
    //                    _set_new_handler( 0 );
    //                    return 0;
    //                }
    //            所以我也无计可施,只能舍弃set_new_handler的作用.

    _cs.Enter();
    void* p = _malloc_dbg( nSize, _NORMAL_BLOCK, lpszFileName, nLine );
    _cs.Leave();
    return p;
}
void __cdecl operator delete( void* p, const char* /*lpszFileName*/, int /*nLine*/ )
{
    _cs.Enter();
    _free_dbg( p, _CLIENT_BLOCK );
    _cs.Leave();
}

#endif


3. 事例代码
#include <iostream>
#include "debug_new.h"
using namespace std;

int main( void )
{
    REG_DEBUG_NEW;

    char* p = new char[2];
    p[0] = 'A';
    p[1] = 'B';

    cout << "--End--" << endl;
    return 0;
}


4. 结果输出
在VC++ IDE中按F5调试运行将会在Output窗口的Debug页看到类似如下的提示:
……
Dumping objects ->
d:\test.cpp(10) : {45} normal block at 0x003410C8, 2 bytes long.
Data: <AB> 41 42
Object dump complete.
……

posted on 2004-10-28 04:49 周星星 阅读(41659) 评论(34)  编辑 收藏

评论

# 好帖! 2004-10-28 05:01 一笑
收藏ing...

# re: VC++6.0中内存泄漏检测 2004-10-30 01:26 lxwde
我也支持一下楼主

# re: VC++6.0中内存泄漏检测 2004-11-01 10:28 zhuyie
默认显示的字体好像太小了,呵呵;


# to zhuyie: 2004-11-01 21:40 周星星
不知道为什么字体和大小这几天变了,而且不受我控制,以前还好好的。

# re: VC++6.0中内存泄漏检测 2004-11-03 09:39 soloist
对"头文件new中的set_new_handler是stub的"这句话中"stub"的意思我有点不太明白,是不是指set_new_handler本身并没有实现任何功能,只是提供了一个接口,真正功能的完成靠的是在内部调用_set_new_handler?
另外,在实际开发的时候_CrtSetDbgFlag这个函数应该越早调用越好,因为C++中全局对象的初始化是在main函数之前,而在它们的构造函数里极有可能做了分配堆内存的动作,如果我们仅仅在刚进入main的时候调用_CrtSetDbgFlag,则无法检测到有可能由上述全局对象引起的内存泄漏。我的建议是定义一个类,在它的构造函数里调用_CrtSetDbgFlag,然后在main函数所在的CPP里首先定义一个上述类的全局对象。当然,C++标准不保证全局变量初始化的顺序,所以先于它的全局变量初始化引发的堆内存分配仍然不受监控,但是这个方法毕竟能扩大一点监控范围,对吧?
一个问题和一个建议,还请周星星兄指正。


# to soloist: 2004-11-03 22:03 周星星
VC++6.0中的set_new_handler:
/***
* WARNING: set_new_handler is a stub function that is provided to
* allow compilation of the Standard Template Library (STL).
* Do NOT use it to register a new handler. Use _set_new_handler instead.
* However, it can be called to remove the current handler:
* set_new_handler(NULL); // calls _set_new_handler(NULL)
*******************************/
new_handler __cdecl set_new_handler (new_handler new_p)
{
// cannot use stub to register a new handler
assert(new_p == 0);

// remove current handler
_set_new_handler(0);

return 0;
}


对于第二点非常感谢,我当初甚至想使用
#pragma comment(linker, "/ENTRY:Inti")
void __cdecl Init( void )
{
……
}
来让它一开始就起作用,但……^_^,不会,免得用法弄错了,遗笑大方,要不你帮我改改?:)


# re: 周星星 2004-11-04 10:48 soloist
用#pragma comment(linker, "/ENTRY:Init"),我也试了一下。如果在Init中做完了指定的动作后直接调用main或者WinMain的话我觉得不太安全,因为通过观察代码发现在诸如mainCRTStartup这样的默认入口函数中系统做了许多检查和初始化的工作(好象挺复杂,我也没看懂)。但是如果要显式地调用它又得导入不少VC的内部文件(而且我也没试成功,如果你能成功调用的话,烦请告诉方法与具体设置),将来用新的开发工具会否出问题就未可知了。
我觉得我上次提的建议也不很好,还不如直接在你的operator new的入口处加上对_CrtSetDbgFlag的调用,反正它也几乎不耗什么时间。这样不管任何地方用到new都能保证DbgFlag标志已经正确设置了。呵呵,我实在想不到其它的更好方法了^_^。
另外还建议(为什么我的话这么多?)将你的_CriSec _cs全局对象定义改成:

_CriSec& _cs()
{
static _CriSec s_cs;

return s_cs;
};

而所有用到_cs的地方改成_cs()。因为全局对象初始化顺序不能确定,所以有可能当其它全局变量在初始化中调用new时_cs本身还没有被初始化。用这种函数的形式可以保证任何时候通过_cs()得到的是一个被正确初始化的_CriSec对象的引用。

# to soloist: 2004-11-04 21:51 周星星
谢谢你的热心指正,两个观点都非常正确,我有空就改掉它。

# 很困惑,希望得到指点一下 2004-11-09 07:47 笑柄
1.新建win32 console application 取名字test
2.new file ->c++ header debug_new.h,copy...;
3.new file ->c++ source debug_new.cpp,copy...;
4.new file ->c++ source test.cpp,copy...;
5.rebuild all
6.f5
出来下面这个,我是VC6.0+win2003s,好象都没打补丁
Loaded 'ntdll.dll', no matching symbolic information found.
Loaded 'C:\WINDOWS\system32\kernel32.dll', no matching symbolic information found.
The thread 0x784 has exited with code 0 (0x0).
The program 'E:\MYPROJECT\test\Debug\test.exe' has exited with code 0 (0x0).


# to 笑柄: 2004-11-09 21:39 周星星
我没有win2003s,等我有了,我测试一下。谢谢你告诉我这个错误!

# VC 6.0中内存泄漏检测[TrackBack] 2004-11-09 09:05 NetSniffer
Ping Back来自:blog.csdn.net
NetSniffer引用了该文章,地址:http://blog.csdn.net/netsniffer/archive/2004/11/09/173437.aspx

# re: VC++6.0中内存泄漏检测 2004-11-19 05:43 kevie221@hotmail.com
我跟笑柄得到差不多的结果,我是2000+vc6.0,结果如下:
Loaded 'C:\WINNT\system32\ntdll.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\KERNEL32.DLL', no matching symbolic information found.
Loaded 'C:\Program Files\rising\rav\ApiHook.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\ADVAPI32.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\rpcrt4.dll', no matching symbolic information found.
Loaded 'C:\Program Files\rising\rav\Memmon.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\USER32.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\GDI32.DLL', no matching symbolic information found.
Loaded 'C:\WINNT\system32\imm32.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\lpk.dll', no matching symbolic information found.
Loaded 'C:\WINNT\system32\usp10.dll', no matching symbolic information found.
The thread 0x248 has exited with code 0 (0x0).
The thread 0x4D0 has exited with code 0 (0x0).
The program 'C:\PROGRAM FILES\MICROSOFT VISUAL STUDIO\MYPROJECTS\debug_new\Debug\debug_new.exe' has exited with code 0 (0x0).
请问期望的结果为什么没有出现?盼望答复

# re: VC++6.0中内存泄漏检测 2004-11-23 22:01 竹叶
--------------------Configuration: test - Win32 Debug--------------------
Compiling...
test.cpp
debug_new.cpp
Linking...
LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16
Debug/test.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

test.exe - 2 error(s), 0 warning(s) 这是为何?

# re: VC++6.0中内存泄漏检测 2004-12-24 05:02 JerryZ
  很多人运行**的例子代码都没有得到预期的结果,我也是,我看了 MSDN 相关资料后明白了,也许是**留了一手,下面我来揭开谜底,呵呵:

1、检测内存泄漏的基本工具是调试器和 CRT 调试堆函数。为了使用调试堆函数,必须在要调试的程序中添加下面的语句:

#define _CRTDBG_MAP_ALLOC
#include<stdlib.h>
#include<crtdbg.h>

  必须保证上面声明的顺序,如果改变了顺序,可能不能正常工作。<crtdbg.h>的_malloc_dbg和_free_dbg将取代标准的malloc和free函数出现在DEBUG版中,它可以跟踪内存的分配和释放。但是这只会在DEBUG版本中发生(当#define _DEBUG的时候),而Release版本仍使用标准的malloc和free功能。
  #define _CRTDBG_MAP_ALLOC表示使用CRT堆函数的相应的DEBUG版本。这个定义不是必须的,但是没有它,内存泄漏报告中的信息不是很详细。

2、一旦你已经添加了刚才的声明,你就能够通过在程序中加入下面的代码来报告内存泄漏信息:

_CrtDumpMemoryLeaks();

当在DEBUG模式下运行程序时,在Output窗口的Debug页会显示内存泄漏的信息,例如:

Detected memory leaks!
Dumping objects ->
c:\program files\microsoft visual studio\vc98\include\crtdbg.h(552) : {45} normal block at 0x00441BA0, 2 bytes long.
Data: <AB> 41 42
c:\program files\microsoft visual studio\vc98\include\crtdbg.h(552) : {44} normal block at 0x00441BD0, 33 bytes long.
Data: < C > 00 43 00 CD CD CD CD CD CD CD CD CD CD CD CD CD
c:\program files\microsoft visual studio\vc98\include\crtdbg.h(552) : {43} normal block at 0x00441C20, 40 bytes long.
Data: < C > E8 01 43 00 16 00 00 00 00 00 00 00 00 00 00 00
Object dump complete.

MSDN 中讲得非常详细,有什么问题请大家多看多读,肯定会有收获。不啰嗦了。祝大家圣诞快乐!

# re: VC++6.0中内存泄漏检测 2005-01-18 06:56 meteor135
我觉得只有这两个文件就够了,test.cpp中可以不显式出现任何处理动作,而由debug_new.cpp中的全局类变量的构造和析构过程完成。这样就摆脱了应用工程和调试工具的耦合。不知道大家对此有什么看法请评论。

注:工程中只需要加入debug_new.cpp

///////////////////////////////////////////////////
// test.cpp

#include <iostream>
using namespace std;

int main( void )
{
char* p = new char[2];
p[0] = 'A';
p[1] = 'B';

cout << "--End--" << endl;

return 0;
}

///////////////////////////////////////////////////
//debug_new.cpp

#ifdef _DEBUG
#include <windows.h>
#include <crtdbg.h>

class _DebugUtil
{
public:
_DebugUtil()
{
_CrtSetDbgFlag( _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF );
}
~_DebugUtil()
{
_CrtDumpMemoryLeaks();
}
} _debugUtil;

class _CriSec
{
CRITICAL_SECTION criSection;
public:
_CriSec()
{
InitializeCriticalSection( &criSection );
}
~_CriSec()
{
DeleteCriticalSection( &criSection );
}
void Enter() { EnterCriticalSection( &criSection ); }
void Leave() { LeaveCriticalSection( &criSection ); }
} _cs;

void _RegDebugNew( void )
{
_CrtSetDbgFlag( _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF );
}
void* __cdecl operator new( size_t nSize, const char* lpszFileName, int nLine )
{
_cs.Enter();
void* p = _malloc_dbg( nSize, _NORMAL_BLOCK, lpszFileName, nLine );
_cs.Leave();
return p;
}
void __cdecl operator delete( void* p, const char* /*lpszFileName*/, int /*nLine*/ )
{
_cs.Enter();
_free_dbg( p, _CLIENT_BLOCK );
_cs.Leave();
}

#endif


# re: VC++6.0中内存泄漏检测 2005-01-18 06:58 meteor135
上面的
void _RegDebugNew( void )
{
_CrtSetDbgFlag( _CRTDBG_REPORT_FLAG | _CRTDBG_LEAK_CHECK_DF );
}

也不需要了。

# to meteor135: 2005-01-18 21:56 周星星
谢谢!

# re: VC++6.0中内存泄漏检测 2005-01-21 11:13 lift

#ifndef _DEBUG_NEW_H_
#define _DEBUG_NEW_H_

#ifdef _DEBUG

#ifdef new
#undef new
#endif

#define CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

#include <windows.h>

namespace __impl {
class CCriticalSection {
public:
CCriticalSection() { ::InitializeCriticalSection( &m_cs ); }
~CCriticalSection() { ::DeleteCriticalSection( &m_cs ); }
void Enter() { ::EnterCriticalSection( &m_cs ); }
void Leave() { ::LeaveCriticalSection( &m_cs ); }
private:
CRITICAL_SECTION m_cs;
};

class CDumbCS {
public:
void Enter() { }
void Leave() { }
};

class CGuard {
public:
#ifdef _MT
typedef CCriticalSection lock_type;
#else
typedef CDumbCS lock_type;
#endif

static lock_type* GetLock() {
static lock_type lock;
return &lock;
}

public:
CGuard() { GetLock()->Enter(); }
~CGuard() { GetLock()->Leave(); }
};

class CDebugEnv {
public:
CDebugEnv() {
::_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
}
};
}

// normal
inline
void* __cdecl operator new( size_t nSize, const char* lpszFileName, int nLine )
{
static __impl::CDebugEnv __dbgEnv;
__impl::CGuard guard;
return ::_malloc_dbg( nSize, _NORMAL_BLOCK, lpszFileName, nLine );
}

// 当"new表达式调用的构造函数抛出异常"时可以正确地释放内存
inline
void __cdecl operator delete( void* p, const char* /*lpszFileName*/, int /*nLine*/ )
{
__impl::CGuard guard;
::_free_dbg( p, _NORMAL_BLOCK );
}

// normal
inline
void __cdecl operator delete( void* p)
{
__impl::CGuard guard;
::_free_dbg( p, _NORMAL_BLOCK );
}

#define new new(__FILE__, __LINE__)

#endif // _DEBUG


#endif


# re: VC++6.0中内存泄漏检测 2005-01-21 11:22 lift
作为一个头文件包含就可以了,不需cpp文件
优化了单线程时的情况
全局对象初始化的问题已经考虑进去了
必须提供两个delete, 一个在new对象而构造函数抛出异常时由系统自动调用,一个为用户delete时调用


# re: VC++6.0中内存泄漏检测 2005-02-12 22:07 achun
MS的crtdbg.h 真是莫名其妙!明明是
#ifndef _DEBUG
.....
#define _CrtSetDbgFlag(f)                   ((int)0)
那么在debug mode下应该无法使用_CrtSetDbgFlag的,他怎么用的呀?毫无道理!

# re: VC++6.0中内存泄漏检测 2007-06-05 16:42 Aplia
会和Direct3D中的d3dx9math.h冲突

# re: VC++6.0中内存泄漏检测 2007-06-12 10:20 x68251
我看了各位的评论,在我的代码中调试出现了下面的问题,请各位帮忙解决,谢谢!
Dumping objects ->
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\plex.cpp(29) : {213} normal block at 0x04AFBE60, 124 bytes long.
 Data: <                > 00 00 00 00 00 00 00 00 06 0F 02 00 20 BB AF 04 
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\map_pp.cpp(69) : {212} normal block at 0x04AFBDE0, 68 bytes long.
 Data: <d               > 64 BE AF 04 00 00 00 00 00 00 00 00 00 00 00 00 
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\plex.cpp(29) : {211} normal block at 0x04AFBD28, 124 bytes long.
 Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 E0 BC AF 04 
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\occcont.cpp(337) : {210} normal block at 0x04AFBCE0, 12 bytes long.
 Data: <            > 00 00 00 00 20 BB AF 04 00 00 00 00 
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\occmgr.cpp(781) : {190} client block at 0x04AFBB20, subtype c0, 236 bytes long.
a CCmdTarget object at $04AFBB20, 236 bytes long
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\plex.cpp(29) : {189} normal block at 0x04AFBA68, 124 bytes long.
 Data: <            p   > 00 00 00 00 00 00 00 00 00 00 00 00 70 86 AF 04 
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\occmgr.cpp(788) : {188} normal block at 0x04AF8670, 4 bytes long.
 Data: < : x> DC 3A 1F 78 
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\occmgr.cpp(143) : {183} client block at 0x04AFA330, subtype c0, 128 bytes long.
a CCmdTarget object at $04AFA330, 128 bytes long
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\ctlcore.cpp(574) : {179} client block at 0x04AFA0C8, subtype c0, 88 bytes long.
a CWnd object at $04AFA0C8, 88 bytes long
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\ctlview.cpp(239) : {159} normal block at 0x04AF9E30, 12 bytes long.
 Data: <        L   > 01 00 00 00 00 00 00 00 4C F6 1D 00 
.\WebICTCtrl.cpp(14) : {150} client block at 0x04AF9B68, subtype c0, 652 bytes long.
a WebICTCtrl object at $04AF9B68, 652 bytes long
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\dllmodul.cpp(133) : {146} client block at 0x04AF9AE8, subtype c0, 64 bytes long.
a CDynLinkLibrary object at $04AF9AE8, 64 bytes long
{141} client block at 0x04AF85F0, subtype c0, 64 bytes long.
a CDynLinkLibrary object at $04AF85F0, 64 bytes long
{139} normal block at 0x04AF9808, 52 bytes long.
 Data: <                > 08 98 AF 04 08 98 AF 04 08 98 AF 04 CD CD CD CD 
{63} client block at 0x04AF3218, subtype c0, 64 bytes long.
a CDynLinkLibrary object at $04AF3218, 64 bytes long
Object dump complete.

# re: VC++6.0中内存泄漏检测 2007-06-12 10:24 x68251
忘了说,我没有f盘,搜索也没有找到上面所说的.cpp文件.
怎样用它的内存编号调试???


# re: VC++6.0中内存泄漏检测 2007-07-17 15:56 小字辈
MFC工程的程序 是不是有下面的就行了
#ifdef _DEBUG
  #define new DEBUG_NEW
  #undef THIS_FILE
  static char THIS_FILE[] = __FILE__;
  #endif


# re 小字辈: 2007-07-17 18:07 周星星
MFC用向导生成的代码会自己加

# re: VC++6.0中内存泄漏检测 2007-09-14 16:18 JUSTIN
# re: VC++6.0中内存泄漏检测 2004-12-24 05:02 JerryZ 
应该不是这个文件有泄露才对 啊,应该是***。CPP

# re: VC++6.0中内存泄漏检测 2007-12-04 11:01 Little_Char
我的工程很庞大 而且都是.c文件 编译环境是VS2005 请问能不能用以上的方法呢 
另外我的大工程有很多.dsw工程 请问应该代码应该加在哪一个工程呢:是在大工程的main函数中 or 具体泄漏的地方??

# re: VC++6.0中内存泄漏检测 2008-01-22 22:06 redwolf
好文章我放在我博客上了,不介意吧:)

# re redwolf: 2008-01-23 09:20 周星星
当然不介意,请随意