关于内存释放

黑夜愁客 2010-04-12 09:40:13


今天碰到一个比较棘手的内存处理问题。

首先来看一个数据结构:
C代码

typedef struct _IRP_AND_FILTER
{
PIRP pIrp;
PMS_FILTER pFilter;
ULONG OutputBufferLength;
}IrpAndFilter, *PIrpAndFilter;


其中pIrp是一个IRP指针,pFilter指的是一个Filter Driver的实例,最后一个数字式OutputBuffer的长度。接着看代码:
Cpp代码


        pIrpFilter = (PIrpAndFilter)NdisAllocateMemoryWithTagPriority(pFilter->FilterHandle,sizeof(IrpAndFilter),FILTER_ALLOC_TAG, LowPoolPriority);

if(pIrpFilter != NULL)


这里为这个结构分配了一个size为sizeof(IrpAndFilter)的空间。谁分配,谁释放的原则告诉我们等资源不再使用的时候需要释放。现在的问题是:pIrp在内核的调度函数执行完毕,调用IoCompleteRequest(pIrp, IO_NO_INCREMENT);之后仍然不能释放,因为里面还有一个OutputBuffer的数据需要传递给User层,而且估计会在程序关闭时 Cleanup,释放这些资源。然后是pFilter这个是指向Filter实例的指针,用完也不能释放,因为其他部分程序会使用到,而且最后程序在 FilterDetach()释放该资源,现在只剩下OutputBufferLength,这个用完就可以释放了。所以纠结的是现在这个资源怎么办啊?接着看这个资源是如何使用的:
Cpp代码


 Status = PsCreateSystemThread(&threadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
(PKSTART_ROUTINE) sendMyOwnPacketThread,
pIrpFilter
);


以线程的方式传给sendMyOwnPacketThread函数,然后:
C代码

1. VOID
2. sendMyOwnPacketThread(
3. IN PIrpAndFilter pIrpAndFilter
4. )
5. {
6. NTSTATUS Status;
7. //拿到这些资源
8. pFilter = (PMS_FILTER)pIrpAndFilter->pFilter;//get current filter instance
9. pIrp = (PIRP)pIrpAndFilter->pIrp;//get current IPR
10. OutputBuffer = (PUCHAR)pIrp->AssociatedIrp.SystemBuffer;
11. OutputBufferLength = (ULONG)pIrpAndFilter->OutputBufferLength;
12. //使用资源
13.
14. //结束前
15. pIrp->IoStatus.Status = Status;
16. pIrp->IoStatus.Information = bufSize;
17. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
18. PsTerminateSystemThread(STATUS_SUCCESS);//end the thread
19. //是否释放资源
20. //NdisFreeMemory(pIrpAndFilter,sizeof(IrpAndFilter),0);
21. }


我测试过了,释放资源有问题,就如前面说的,两个指针都不能释放,这下就傻眼了,没有释放,程序倒是正常执行,释放反而错了。我知道那两个资源不能在这里释放,可是我Allocate一块空间了,难道就这样了...还是至少要释放ULONG那一块资源呢?不得而知!!望知道的指点一二。
...全文
191 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
黑夜愁客 2010-04-14
  • 打赏
  • 举报
回复
我觉得有人提议说用公有数据结构保存..有些道理
angel_su 2010-04-13
  • 打赏
  • 举报
回复
不是很懂,只知道如果是个内核对象当由内核所拥有,不用自己管理销毁的吧...
黑夜愁客 2010-04-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 cattycat 的回复:]

你分配内存用的是NdisAllocateMemoryWithTagPriority这个函数,最后释放可能也有对应的函数来通过pIrpFilter 指针释放,可能这个释放函数内部释放了outbuffer部分。底层分配的时候记录了一些信息。
而且这部分在分配的时候是连续的,先释放pIrpFilter 内部成员指针的内存,最后释放pIrpFilter 内存。
[/Quote]
关键是对应的两个指针成员对应那块内存不能由我们自己销毁,我就纳闷了。
黑夜愁客 2010-04-13
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 jackyjkchen 的回复:]

引用 2 楼 yexin218 的回复:
这是内核程序,我只懂用wdk自带编译器编译,不过像你这么说可以使用windbg查看变量情况

那个编译器……难道不是VC编译器,不就是多了些库么
[/Quote]是,但是驱动调试,不是简单dbg
jackyjkchen 2010-04-12
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 yexin218 的回复:]
这是内核程序,我只懂用wdk自带编译器编译,不过像你这么说可以使用windbg查看变量情况
[/Quote]
那个编译器……难道不是VC编译器,不就是多了些库么
cattycat 2010-04-12
  • 打赏
  • 举报
回复
你分配内存用的是NdisAllocateMemoryWithTagPriority这个函数,最后释放可能也有对应的函数来通过pIrpFilter 指针释放,可能这个释放函数内部释放了outbuffer部分。底层分配的时候记录了一些信息。
而且这部分在分配的时候是连续的,先释放pIrpFilter 内部成员指针的内存,最后释放pIrpFilter 内存。

白云飘飘飘 2010-04-12
  • 打赏
  • 举报
回复
windbg可以进行内核调试
zbychhaozeng 2010-04-12
  • 打赏
  • 举报
回复
有点难懂!
黑夜愁客 2010-04-12
  • 打赏
  • 举报
回复
这是内核程序,我只懂用wdk自带编译器编译,不过像你这么说可以使用windbg查看变量情况
「已注销」 2010-04-12
  • 打赏
  • 举报
回复
试试 valgrind
或者gcc 运行在异常的时候up一下,看看各个变量的状态

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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