当前位置:网站首页>实现动态库(DLL)之间内存统一管理
实现动态库(DLL)之间内存统一管理
2022-08-02 03:29:00 【ChivenZhang】
问题背景
公司里出现了这么个亟待解决的问题,就是项目中的多个动态库在释放时,由于顺序不当产生使用已析构对象野指针引用问题,导致系统崩溃。因此,个人认为解决这个难题的前提是使用统一的动态库负责内存分配与回收。
注释:对于所有DLL都是以MD编译模式生成,则不存在内存于A堆创建,B堆释放的风险。DLL统一分配仅仅适用于MT编译的模块代码。
设计思路
统一内存管理模块包括:内存分配模块(PMemory.dll),动态库加载模块(PExport.lib),业务模块(PService.exe或dll),其中
PMemory.dll
内存统一分配单元,提供统一的new与delete接口。
PExport.lib
封装动态加载与释放PMemory.dll的逻辑,简化代码编写工作。
PService.[exe/dll/lib]
具体业务逻辑单元。
实现代码
PMemory.dll
#include "PMemory.h"
#include <stdlib.h>
void* p_new(size_t size)
{
return ::malloc(size);
}
void p_delete(void* address)
{
::free(address);
}
PExport.lib
#include "PExport.h"
#include <Windows.h>
#include <stdlib.h>
class _Initial
{
public:
using FunctionNew = void* (*)(size_t);
using FunctionDelete = void (*)(void*);
public:
_Initial() : m_Handle(nullptr), m_FunctionDelete(nullptr), m_FunctionNew(nullptr)
{
m_Handle = ::LoadLibraryA("PMemory.dll");
if (m_Handle)
{
m_FunctionNew = (FunctionNew) ::GetProcAddress(m_Handle, "p_new");
m_FunctionDelete = (FunctionDelete) ::GetProcAddress(m_Handle, "p_delete");
}
}
~_Initial()
{
if (m_Handle)
{
m_FunctionNew = nullptr;
m_FunctionDelete = nullptr;
::FreeLibrary(m_Handle);
m_Handle = 0;
}
}
void* _new(size_t size)
{
if (m_FunctionNew)
{
return m_FunctionNew(size);
}
return nullptr;
}
void _delete(void* address)
{
if (m_FunctionDelete)
{
m_FunctionDelete(address);
}
}
private:
HMODULE m_Handle;
FunctionNew m_FunctionNew;
FunctionDelete m_FunctionDelete;
};
_Initial g_Memory;
void* p_malloc(size_t size)
{
return g_Memory._new(size);
}
void p_free(void* address)
{
g_Memory._delete(address);
}
void p_delete(void* address)
{
g_Memory._delete(address);
}
PService.exe
#include <PExport.h>
class A
{
public:
A(int n, int m) : a(n), b(m) {}
int a = 123;
int b = 321;
};
void main()
{
auto a = p_new<A>(666, 999);
printf("%d %d", a->a, a->b);
p_delete(a);
}
运行截图
总结
至此,虽然开头提及因对象依赖关系不当而导致野指针引用的问题仍然没有得到解决,但却离成功更近了一步。现在能够保证,在任何动态库之间使用接口创建或回收内存,通常不会系统报错。
边栏推荐
猜你喜欢
随机推荐
从Attention到Self-Attention和Multi-Head Attention
蛮力法求解凸包问题
使用Vercel托管自己的网站
电子密码锁_毕设‘指导’
字符串匹配(蛮力法+KMP)
Spark MLlib特征处理 之 StringIndexer、IndexToString使用说明以及源码剖析
引擎开发日志:集成Bullet3物理引擎
uniCloud address book combat
GM7150 CVBS转BT656视频解码芯片详细内容及设计要求
AD PCB导出Gerber文件(非常详细的步骤)
网站开发方案研究
火焰传感器与 Arduino 连接
2019 - ICCV - 图像修复 Image Inpainting 论文导读《StructureFlow: Image Inpainting via Structure-aware ~~》
【Arduino connects DHT11 humidity and temperature sensor】
树莓派入门(1)系统镜像烧录
倍福ET2000侦听器使用
Out of memory error on GPU 0. Cannot allocate xxxGB memory on GPU 0, available memory is only xxx
完全背包问题(动态规划)
D类音频功放NS4110B电路设计
OneNET Studio与IoT Studio对比分析