shared_ptr跨模块边界的问题

本文主要讨论了Windows平台dll中shared_ptr的使用问题。shared_ptr默认用delete释放对象,在dll中会因不同模块内存管理组件不同而出错。虽boost::shared_ptr有get_deleter,但自定义析构方法仍有局限,引用计数问题无法解决。最后怀念Loki的SmartPtr,其基于策略编程可定制销毁。
如果shared_ptr默认是用delete来释放对象的,而delete动作产生的是本模块的代码,这在windows平台的dll中遇到了问题:可执行程序和dll分属不同模块,分别使用各自的内存管理组件。直接delete,无异于把A堆管理器分配的指针让B堆管理其去释放,崩溃还算好的,悄悄的出错,死都不知道怎么死的。
还好,boost::shared_ptr使用了一个叫get_deleter的东西,内部维护了delete的方法。可是,如果我想自定义一个特别的析构方法怎么办?嗯,特化sp_counted_impl_p<>吧!
特化sp_counted_impl_p可以解决大部分问题。可是,引用计数的问题,则是无法解决的:你不可能重写sp_counted_base。如果我想用shared_ptr指向一个com对象,那么,sp_counted_impl_p<>可以让它工作,但是,com对象内的引用计数将不可能正确。
由此,不由的怀念起Loki的SmartPtr来了,强大的基于策略编程的实现!只要将存储策略中的Destory替换成我想要的实现即可实现定制销毁。替换掉OwnershipPolicy就可以。就算Loki不能进boost(老实说,我认为mpl比typelist好),SmartPtr绝对应该比那shared_ptr强多了!
#include "StringLengthEdgeCase.h" #include <algorithm> #include "../utils.h" StringLengthEdgeCase::StringLengthEdgeCase(std::shared_ptr<StringBase> obj, std::mt19937 &rand) : IntegerEdgeCases(obj, rand) { } std::pair<int64_t, int64_t> StringLengthEdgeCase::get_limits(std::shared_ptr<StringBase> obj) { int64_t max_ = obj->mutator_config.max_output_size * 8; int64_t size = obj->calculate_bit_size(); int64_t limit = std::max(max_, size); limit = (limit + 7) / 8; max_ = limit; if (obj->max_length != -INT64_MAX) { max_ = std::min(max_, obj->max_length); } int64_t min_ = 0; if (obj->min_length != INT64_MAX) { min_ = std::max(min_, obj->min_length); } return {min_, max_}; } bool StringLengthEdgeCase::supported(std::shared_ptr<StringBase> obj) { auto ptr = std::dynamic_pointer_cast<String>(obj); return (ptr != nullptr); } void StringLengthEdgeCase::perform_mutation(std::shared_ptr<StringBase> obj, std::string value) { uint64_t valueLength = value.size(); obj->mutated_value = expand(obj->value, valueLength); obj->mutated = true; } class IntegerEdgeCases : public Mutator { public: void Init(std::shared_ptr<NumberBase> obj) override; void Init(std::shared_ptr<StringBase> obj) override; IntegerEdgeCases(std::shared_ptr<NumberBase> obj, std::mt19937 &rand); IntegerEdgeCases(std::shared_ptr<StringBase> obj, std::mt19937 &rand); virtual std::pair<std::int64_t, std::int64_t> get_limits(std::shared_ptr<NumberBase> obj); virtual std::pair<std::int64_t, std::int64_t> get_limits(std::shared_ptr<StringBase> obj); virtual void perform_mutation(std::shared_ptr<NumberBase> obj, int64_t value); virtual void perform_mutation(std::shared_ptr<StringBase> obj, std::string value); void mutate(std::shared_ptr<NumberBase> obj, std::function<int64_t()> gen); // void mutate(std::shared_ptr<StringBase> obj, std::function<std::string()> gen); void sequential_mutation(std::shared_ptr<NumberBase> obj) override; // void sequential_mutation(std::shared_ptr<StringBase> obj) override; void random_mutation(std::shared_ptr<NumberBase> obj) override; // void random_mutation(std::shared_ptr<StringBase> obj) override; std::int64_t get_count() override; std::int64_t sequential1(); std::int64_t sequential2(); std::int64_t random1(); std::int64_t random2(); std::int64_t space; std::int64_t full_space; bool sequential_generator = false; bool random_generator = false; std::int64_t min_; std::int64_t max_; EdgeCaseGenerator generator; }; 这是现有的cpp实现,距离实现StringLengthEdgeCase还有多少差距?为我进行修改
07-02
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值