搞定内存分配的问题!加分中(114分)

APIer 2001-04-13 10:12:00
为公司做的一个小型的mfc和DirectX的风装,我重载了全局的new 和delete 操作符,提供一个调试版和一个释放版本,这个我现在完成了,每次分配内存我都多分配16个字节,开始2个结尾两个都是标志,用来释放的时候检测指针是否越界,在调试版本中我向一个全局的内存管理类纪录所有的内存分配和释放,程序推出后存盘,以便知道什么时候分配了内存,什么时候释放了,但是,我发现在程序推出的时候这全局的内存管理变量最先析构了,以至于后面释放的内存不能记载而达不到了解所有的内存什么时候释放的,我要怎么样才能让我的内存纪录类再所有的变量构造之前构造,在所有的析构之后析构呢?回答问题大大的加分:)
...全文
126 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
APIer 2001-04-15
  • 打赏
  • 举报
回复
In355Hz(好象一条狗) 
你说的有道理,我申明成为了static,发现我的程序没有内存泄漏了,呵呵真高兴:)
给分了!
In355Hz 2001-04-14
  • 打赏
  • 举报
回复
我想把变量申明为静态全局变量可能好一点。静态变量一般会在其他全局变量之前构造,之后被解构。
to APIer:Hi, 又见面了。
duz 2001-04-14
  • 打赏
  • 举报
回复
你重载了new和delete操作符以后,只有在你调用new和delete申明的内存才会使用你的new和delete函数。所以当你的全局内存管理变量的析构函数被调用时,所有你的代码已经都被执行了,也就不会再有delete语句被调用了,你可以在这里查看你的内存管理变量里是否还包含某些没有被释放的内存,如果有,就说明有内存泄漏了(即调用了new却没有使用delete),注意,你申明的全局变量(而不是通过new动态构造的变量)不会调用new来申明内存)。
yoci 2001-04-14
  • 打赏
  • 举报
回复
gz
APIer 2001-04-14
  • 打赏
  • 举报
回复
In355Hz(好象一条狗) 
呵呵又见到了你,你的建议每次都非常好,我等下试验一下。非常谢谢,有机会聊天,qq我一般都隐身的:)
dingsg 2001-04-14
  • 打赏
  • 举报
回复
使用purify查一下!
APIer 2001-04-14
  • 打赏
  • 举报
回复
UP
zhaowuqing 2001-04-13
  • 打赏
  • 举报
回复
最头疼的就是这东西
APIer 2001-04-13
  • 打赏
  • 举报
回复
smq() :
多谢了,使用内存快照,不错的建议:)还有我现在的内存就是你说的那样分配的。
但是我知道了内存发生了泄漏还不够阿,我还想要知道在那一行,那个文件申明的没有释放,所以我需要一个全局的内存管理器,这个管理器的生存期必须是程序的生存期,这样才能一个不漏的捕获所有的内存操作,那么这个管理期怎么申明呢?
APIer 2001-04-13
  • 打赏
  • 举报
回复
smq() :
多谢了,使用内存快照,不错的建议:)还有我现在的内存就是你说的那样分配的。
但是我知道了内存发生了泄漏还不够阿,我还想要知道在那一行,那个文件申明的没有释放,所以我需要一个全局的内存管理器,这个管理器的生存期必须是程序的生存期,这样才能一个不漏的捕获所有的内存操作,那么这个管理期怎么申明呢?换一句话说,我希望一个再所有其他对象构造之前构造,在所有其他对象析构之后析构。
smq 2001-04-13
  • 打赏
  • 举报
回复
内存漏洞的检查
其实在你的Debug版本中所有的有关内存分配的函数都是被重载过的,具体过程是这样的,当你的程序申请内存时,它首先调用一般的内存分配函数分配一块稍大的内存块。在这一内存块中分为四个小块:Heap Information, buffer , User memory block, buffer。第一块为有关堆的信息,比如,申请该内存的地点(文件名,行号),此内存块的类型(如整型,浮点,或某一类的对象)等等。第二块是一个缓冲区,用于截获用户对其申请内存使用越界的情况。第三块是真正给用户的内存,返回的指针也是指向这儿。第四块也是一个缓冲区,作用同第二块。
当你申请的内存均被记录在案后,要检查内存漏洞就比较容易了,粗略地说,假如你要检查某一程序段是否有内存漏洞,你只需在这一程序 段的开始要求系统为你做一个内存使用情况的映象,记录下程序开始时的内存使用情况,然后在程序段的末尾再使系统为你做一次内存映象,比较两次映象,以检查是否有没释放的内存,假如有未释放的内存,根据这一块中有关分配情况的信息来告诉用户在那儿申请的内存没释放。
具体地讲检查内存漏洞需要以下几个步骤:
 在你所检测的程序段的开始处建立一个CmemoryState对象,调用其成员函数Checkpoint,以取得当前内存使用情况的快照;
 在你所检测的程序段的末尾处再建立一个CmemoryState 对象,调用其成员函数Checkpoint ,以取得当前内存使用情况的快照;
 再建立第三个CmemoryState 对象,调用其成员函数Difference,把第一个CmemoryState对象和第二个CmemeoryState对象作为其参数.,如果两次内存快照不相同,则该函数返回非零,说明此程序 段中有内存漏洞。下面我们来看一个典型的例子:

// Declare the variables needed
#ifdef _DEBUG
CMemoryState oldMemState, newMemState, diffMemState;
OldMemState.Checkpoint();
#endif
// do your memory allocations and deallocations...
CString s = "This is a frame variable";
// the next object is a heap object
CPerson* p = new CPerson( "Smith", "Alan", "581_0215" );
#ifdef _DEBUG
newMemState.Checkpoint();
if( diffMemState.Difference( oldMemState, newMemState ) )
{
TRACE( "Memory leaked!\n" );
}
#endif
APIer 2001-04-13
  • 打赏
  • 举报
回复
顶一下,要不就被淹没了:)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧