当前位置:网站首页>实现动态库(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);
}
运行截图

总结
至此,虽然开头提及因对象依赖关系不当而导致野指针引用的问题仍然没有得到解决,但却离成功更近了一步。现在能够保证,在任何动态库之间使用接口创建或回收内存,通常不会系统报错。
边栏推荐
猜你喜欢

Compatible with C51 and STM32 Keil5 installation method

字符串匹配(蛮力法+KMP)

uniCloud使用

【Arduino 连接GP2Y1014AU0F 灰尘传感器】

【plang1.4.3】语言新特性:集合

2020 - AAAI - Image Inpainting论文导读《Learning to Incorporate Structure Knowledge for Image Inpainting》

【Arduino使用旋转编码器模块】

MPU6050 加速度计和陀螺仪传感器与 Arduino 连接

回溯法 & 分支限界 - 2
![[Popular Science Post] I2C Communication Protocol Detailed Explanation - Partial Software Analysis and Logic Analyzer Example Analysis](/img/be/9b23a798557222bab68c67bf9170af.png)
[Popular Science Post] I2C Communication Protocol Detailed Explanation - Partial Software Analysis and Logic Analyzer Example Analysis
随机推荐
sacalatest AnyFunSuite:no implicits found for parameter pos
PCIE电路设计
博达工业云与阿里云对比
[Arduino connected to GP2Y1014AU0F dust sensor]
AD8307对数检波器
【NTC 热敏电阻与 Arduino 读取温度】
远程调试PLC,到底如何操作?
2020 - AAAI - Image Inpainting论文导读《Learning to Incorporate Structure Knowledge for Image Inpainting》
USB HUB USB集线器电路设计
Cadence allegro导出Gerber文件(制板文件)图文操作
将ORCAD原理图导入allegro中进行PCB设计
OneNET Studio与IoT Studio对比分析
《scala 编程(第3版)》学习笔记2
【nRF24L01 与 Arduino 连接实现无线通信】
Scala,Spark依赖jar包冲突解决方法
移动云物联网预研及阿里云开发对比分析
GM8775C MIPI转LVDS调试心得分享
R语言 —— 多元线性回归
简单的RC滤波电路
PCB Design Ideas