18143453325 在线咨询 在线咨询
18143453325 在线咨询
所在位置: 首页 > 营销资讯 > 行业动态 > 坑三:如何避免Double Free

坑三:如何避免Double Free

时间:2022-04-28 21:12:01 | 来源:行业动态

时间:2022-04-28 21:12:01 来源:行业动态

Standard Marshalling Service/Interop marshaller总是试图释放Unmanaged侧代码分配的内存9,这会带来Double Free的问题,如果碰到这种问题,程序就会直接崩溃。

引用资料中举了以下例子:

BSTRMethodOne(BSTRb){returnb;}

如果这段代码直接从Unmanaged侧DLL中直接执行,不会发生任何额外的内存释放;但是当你从Managed侧调用这个方法时,b会被释放两次。

而更让人抓狂的是,并没有相应的信息提示究竟是哪个指针,哪个字段被Double Free了,你唯一能做的就是一点点加代码来验证自己猜测。所以,严格来说,并没有一个万无一失的方案来避免Double Free,你唯一能做的就是通过测试来验证结果(有点盲拧魔方的味道了)。

有两个基本的方法来解决Double Free的问题:

1、按照官方文档建议,在Unmanaged侧通过使用CoTaskMemAlloc来分配内存,通过此种方法分配的内存,除非显式调用了CoTaskMemFree方法(在Unmanaged侧或者Managed侧均可以调用),Interop Marshaller会严格保证不去释放该内存。使用这种方法可以灵活的在任意一侧分配内存,并在合适的时候在另一侧释放内存。

2、但上面这种方法貌似仅适用于Windows平台,在macOS下没有办法使用(需要引用win32base.dll相关实现)。在macOS下仅能通过在Mananged侧调用Marshal.AllocCoTaskMem()方法分配内存,并通过Marshal.FreeCoTaskMem()来在同一侧进行释放(按照此方法分配的内存指针传入Unmanaged侧后,不要进行任何释放即可)。另外有一个不太可靠的workaround是:在Unmanaged一侧创建的内存指针尽量通过IntPtr传递,并在可能的时候将对象中一些指针类型的属性值置空,以避免Double Free的发生。

关键词:避免

74
73
25
news

版权所有© 亿企邦 1997-2022 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭