SGI STL 中, 没有使用的内存会以链表的方式挂载在 free_list
中, 如果 free_list
中有足够的内存, 那么直接返回. 但是内存的回收并不一定是按照内存的申请顺序来的, 这就导致链表的第一个并不一定是 chunk 的头部内存
而如果要回收 chunk 部分的内存, 必须要知道其 malloc()
回传的头部地址, 然后将其传给 free()
. 虽然这个地址一定会在 free_list
中存在, 但是如何知道呢? 目前唯一能够想到的方法就是有一个动态的 void *[]
数组, 记录头部地址
因为在 chunk_alloc()
中, 如果出现 start_free == end_free
的情况, 在有足够内存的情况下, 也就是 malloc()
成功, start_free
和 end_free
都会被覆盖. 而 chunk_alloc()
函数中并没有任何操作是去记录原来的地址的
因此, 我查看了 STLport 5.2.1 中 allocators.cpp
的源码, 有关 chunk 内存的回收, 我找到这些代码 :
void __node_alloc_impl::_S_chunk_dealloc() {
_Obj *__pcur = _S_chunks, *__pnext;
while (__pcur != 0) {
__pnext = __pcur->_M_next;
__stlp_delete_chunck(__pcur);
__pcur = __pnext;
}
_S_chunks = 0;
_S_start_free = _S_end_free = 0;
_S_heap_size = 0;
memset(__REINTERPRET_CAST(char*, __CONST_CAST(_Obj**, &_S_free_list[0])), 0, _STLP_NFREELISTS * sizeof(_Obj*));
}
以及
void __node_alloc_impl::_S_chunk_dealloc() {
// Note: The _Node_alloc_helper class ensures that this function
// will only be called when the (shared) library is unloaded or the
// process is shutdown. It's thus not possible that another thread
// is currently trying to allocate a node (we're not thread-safe here).
//
// Clear the free blocks and all freelistst. This makes sure that if
// for some reason more memory is allocated again during shutdown
// (it'd also be really nasty to leave references to deallocated memory).
_S_free_mem_blocks.clear();
_S_heap_size = 0;
for (size_t __i = 0; __i < _STLP_NFREELISTS; ++__i) {
_S_free_list[__i].clear();
}
// Detach list of chunks and free them all
_Obj* __chunk = _S_chunks.clear();
while (__chunk != 0) {
_Obj* __next = __chunk->_M_next;
__stlp_delete_chunck(__chunk);
__chunk = __next;
}
}
一样的名称, 所以肯定是由 macro 进行选择
与 《STL 源码剖析》中相对应的 chunk_dealloc()
应该是第一段
在第一段中, 其实就是不断地去 __stlp_delete_chunck(__pcur)
; 但实际上这个函数只是调用 free()
或者 ::operator delete()
, 对于 free_list
中每一小段内存都是用 free()
或者 ::operator delete()
. 这好像是不可行的, 所以对此, 我写了一小段 demo :
#include <iostream>
using namespace std;
union x {
x *next;
char client_data[0];
};
int main(int argc, char *argv[]) {
auto p {malloc(sizeof(x) * 2)};
auto x_ptr1 {static_cast<x *>(p)};
auto x_ptr2 {static_cast<x *>(p) + 1};
free(x_ptr2);
free(x_ptr1);
}
最终的结果就是 pointer being freed was not allocated
* set a breakpoint in malloc_error_break to debug
Terminated due to signal: ABORT TRAP (6)
所以这并不可行
想请教各位, SGI STL 最终是如何对 chunk 内存进行回收的?
答案是不释放,由 OS 负责回收
之前问了不少人,有些人没懂有些人给出错误答案
https://jonny.vip/2019/07/16/...