__pool<true>的销毁
终于,我们来到了最后一站,本节完后,整个mt allocator源码分析也就结束了。和__pool<false>一样,_M_destroy函数其实从未被调用过,但是为了保持设计的完整性,这个函数还是有意义的。
<mt_allocator.cc>
209 void
210 __pool<true>::_M_destroy() throw()
_M_destroy函数原型。
211 {
212 if (_M_init && !_M_options._M_force_new)
213 {
214 if (__gthread_active_p())
判断是否支持多线程。
215 {
216 for (size_t __n = 0; __n < _M_bin_size; ++__n)
217 {
218 _Bin_record& __bin = _M_bin[__n];
219 while (__bin._M_address)
220 {
221 _Block_address* __tmp = __bin._M_address->_M_next;
222 ::operator delete(__bin._M_address->_M_initial);
223 __bin._M_address = __tmp;
归还每个bin向OS申请过的内存块,这个信息是在_M_address里存储的。虽然某些用户使用的内存块可能在线程间传递,但是从OS直接申请的内存块却是从不会混淆的。
224 }
225 ::operator delete(__bin._M_first);
226 ::operator delete(__bin._M_free);
227 ::operator delete(__bin._M_used);
228 ::operator delete(__bin._M_mutex);
释放bin的辅助数据。
229 }
230 }
231 else
在没有多线程支持的时候,采取的操作。
232 {
233 for (size_t __n = 0; __n < _M_bin_size; ++__n)
234 {
235 _Bin_record& __bin = _M_bin[__n];
236 while (__bin._M_address)
237 {
238 _Block_address* __tmp = __bin._M_address->_M_next;
239 ::operator delete(__bin._M_address->_M_initial);
240 __bin._M_address = __tmp;
241 }
242 ::operator delete(__bin._M_first);
同样是释放从OS申请的内存块,只是bin的辅助数据这时要少些。
243 }
244 }
245 ::operator delete(_M_bin);
246 ::operator delete(_M_binmap);
释放bin数组和_M_binmap映射数组。
247 }
248 }
至此,对mt allocator的源码分析全部完成了。其实这篇文章并没有覆盖mt allocator所有的源码,因为我觉得没有必要把每个角落都交代得清清楚楚,有时让读者自己思考一下,会更有效果。由于本人水平有限,文章中难免出现谬误之处,欢迎广大读者批评和指正,谢谢!