分享

回调函数中直接调用底层API导致的corrupted double

 waitingnothing 2017-04-13
显示模块在释放内存时,提示corrupted double-linked list错误。怀疑是内存泄露,调查了一整天,后来发现某一个通信模块只要不调用其下层的某个API就没有问题。其原因是:该通信模块把对此API的调用写在了回调函数当中。
因为回调函数属于下层模块工作流的一部分,所以要避免在回调函数中直接调用下层的API。
设想一下,上下两层模块运行在不同的线程中,下层提供如下3个接口,FunctionA() 和 NotifyOK(),FunctionB(),其中NotifyOK函数由上层编写、由下层回调。工作流程是:当调用下层的FunctionA之后,要等待下层的回调通知NotifyOK(),之后再调用FunctionB()。而在下层的实现中,当FunctionB被调用时将释放某段内存,这样的话,如果上层在NotifyOK回调函数中调用FunctionB的话,便会产生这样的隐患:假如下层在通过NotifyOK通知上层之后使用了这段内存,便会出现内存泄露(因为其空间已经在NotifyOK回调中被提前释放了)。
安全的做法是:上层在收到NotifyOK之后,不是立即开始进行之后的工作流(调用FuntionB),而是以发消息的方式通知自己进行后续处理。
至于错误发生的时机,是因为释放内存时,堆管理器才会检查标记,发现内存泄露。
另外,还搜索了一下相关资料,了解到一些其它的信息。为了提高运算效率,通常分配的内存空间要大于申请空间(地址对齐)。当发生内存泄露,使用了申请外的空间,但没有超出实际分配空间时,有的早期的堆管理器并不会检查出来(操作系统的内存分配实现算法不相同)。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多