自从学习了C语言,老师就教导我们说:对于动态内存的申请和释放,一定要遵守“谁申请,谁释放”的原则。在此原则的指导下,不仅是我、不仅是你,就连特级大师都设计了这样怪怪的函数:
函数 | 说明 | 评论 |
GetWindowText(HWND,LPTSTR,int) | 取得窗口标题。需要在参数中给出保存标题所使用的内存指针,和这块内存的尺寸。 | 晕!我又不知道窗口标题的长度,居然还要我提供尺寸?!没办法,只能估摸着给一个大一些的尺寸吧。 |
sprintf(char *,const char *,...) | 格式化一个字符串。这个函数不用给出缓冲区的长度啦。 | 恩,虽然不用给出长度了,但你敢给个小尺寸吗?哼! |
int CListBox::GetTextLen(int) CListBox::GetText(int,LPTSTR) | 取得列表窗中子项目的标题。需要调用两个函数,先取得长度,然后分配内存,再实际取得标题内容。 | 真烦! |
说实在的,不但函数调用者感觉别扭,就连函数设计者心情也不会爽的,而这一切都是为了满足所谓“谁申请,谁释放”的原则。 解决这个问题最好的方式就是:函数内部根据实际需要动态申请内存,而调用者负责释放。这虽然违背了上述原则,但 COM 从方便性和效率出发,确实是这么设计的。
C语言 | C++语言 | Windows 平台 | COM | IMalloc 接口 | BSTR | |
申请 | malloc() | new | GlobalAlloc() | CoTaskMemAlloc() | Alloc() | SysAllocString() |
重新申请 | realloc() | GlobalReAlloc() | CoTaskRealloc() | Realloc() | SysReAllocString() | |
释放 | free() | delete | GlobalFree() | CoTaskMemFree() | Free() | SysFreeString() |
以上这些函数必须要按类型配合使用(比如:new 申请的内存,则必须用 delete 释放)。在 COM 内部,当然你可以随便使用任何类型的内存分配释放函数,但组件如果需要与客户进行内存的交互,则必须使用上表中的后三类函数族。
1、CoTaskXXX()函数族,其本质上就是调用C语言的函数(malloc...);
2、IMalloc 接口又是对 CoTaskXXX() 函数族的一个包装。包装后,同时增强了一些功能,比如:IMalloc::GetSize()可以取得尺寸,使用 IMallocSpy 可以监视内存的使用;