C++跨模块释放内存

文章探讨了Windows进程中可能存在的多个堆以及如何处理跨模块间的内存申请和释放。提出将所有模块改为MD编译、提供DLL释放接口和统一使用主进程堆的方法。
摘要由CSDN通过智能技术生成

linux一个进程只有一个堆,不要考虑这些问题,但是windows一个进程可能有多个堆,要在对应的堆上释放。

一, MT改MD

一个进程的地址空间是由一个可执行模块和多个DLL模块构成的,这些模块中,有些可能会链接到C/C++运行库的静态版本,有些可能会链接到C/C++运行库的DLL版本。当使用运行库的DLL版本时,由于dll加载到进程中只会在地址空间中存有一份,因此共用的是同一个堆。所以将可执行模块和DLL模块统一修改为MD编译,则可以直接实现跨模块之间的内存申请和释放,而不会存在任何问题。

二, DLL提供释放接口

每个模块自己封装好释放对应内存的接口,分配资源的接口和释放资源的接口成对封装吧,然后外部模块调用就好了。

三, 使用主进程堆申请和释放内存

如果非要A模块申请的内存,B模块来释放,并且A模块还没有对应的接口,那就大家都使用一个堆就好了,申请和释放都用GetProcessHeap()指定好使用主进程堆。
DLL:


```cpp
void* __stdcall Test(int *len)
{
	void* pData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
	if (pData == NULL)
		return NULL;
	//使用的是HEAP_ZERO_MEMORY,会自动把内存块的内容都清零
	//下面这行代码可以不要的
	memset(pData, 0, 100);

	char pBuf[] = "十点十分十分十分";
	memcpy(pData, pBuf, sizeof(pBuf));
	*len = 100;
	return pData;
}

可执行程序:

int main()
{
	HMODULE hLib = LoadLibraryA("Dll1.dll");
	if (nullptr == hLib)
	{
		std::cout << "LoadLibraryA fail, error:" << GetLastError() << std::endl;
		return 0;
	}

	Fun fun = (Fun)GetProcAddress(hLib, "Test");
	if (nullptr == fun)
	{
		std::cout << "GetProcAddress fail, error:" << GetLastError() << std::endl;
		return 0;
	}

	int nLen = 0;
	char *pData = (char*)fun(&nLen);

	std::string strTemp(pData, nLen);

	HeapFree(GetProcessHeap(), 0, pData);

	std::cout << strTemp << std::endl;

	return 0;
}

windows允许一个进程中有多个heap,那么这样就需要指明一块内存要在哪个heap上分配,win32的HeapAlloc函数就是这样设计的,给出一个heap的句柄,给出一个size,然后返回一个指针。每个进程都至少有一个主heap,可以通过GetProcessHeap来获得,其它的堆,可以通过GetProcessHeaps取到。同样,内存释放的时候通过HeapFree来完成,还是需要指定一个堆。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值