伊谢尔伦2017-04-17 14:22:17
知乎上我有看過:
我先問你個問題:指標中是沒有所在記憶體區塊大小的資訊的,那麼 free 怎麼才能知道要釋放的記憶體區塊有多大呢?於是,對於大多數記憶體分配器,malloc 申請的實際記憶體比你要求的空間大幾個字節,裡面儲存了額外的資料來記錄這塊記憶體有多大,一般就是直接存在指標左邊。 free 的時候,就會去讀取指標位址減去一個常數之後的那塊內存,來取得記憶體區塊的資訊。因此如果你 free 一個不指向記憶體區塊開始處的指針,free 的時候就會把其他的資料錯誤解釋成記憶體區塊的信息,(大機率)導致程式崩潰。當然現代的記憶體分配器對於不同大小的記憶體申請,會採用不同的分配策略,但無論策略如何,去 free 一個不是 malloc 來的指針,都是非常危險的舉動。
見:https://www.zhihu.com/questio...
ringa_lee2017-04-17 14:22:17
作業系統是需要知道每個指標分配了多少記憶體的,我們在呼叫delete的時候也沒有告訴作業系統這個指標只想的區域佔用了多少內存,所以肯定有一個地方保存著這個值,而這個值在不同的作業系統有不同的實現,例如最簡單的一種實現就是在每個指標前面一個位元組用來保存記憶體分配的長度,一般作業系統都會提供一個函數來取得這個實際記憶體的大小,例如malloc_size之類的函數。
如果有興趣可以看看redis源碼,zmalloc.h和zmalloc.c
https://github.com/antirez/re...
#if defined(USE_TCMALLOC)
#define ZMALLOC_LIB ("tcmalloc-" __xstr(TC_VERSION_MAJOR) "." __xstr(TC_VERSION_MINOR))
#include <google/tcmalloc.h>
#if (TC_VERSION_MAJOR == 1 && TC_VERSION_MINOR >= 6) || (TC_VERSION_MAJOR > 1)
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) tc_malloc_size(p)
#else
#error "Newer version of tcmalloc required"
#endif
#elif defined(USE_JEMALLOC)
#define ZMALLOC_LIB ("jemalloc-" __xstr(JEMALLOC_VERSION_MAJOR) "." __xstr(JEMALLOC_VERSION_MINOR) "." __xstr(JEMALLOC_VERSION_BUGFIX))
#include <jemalloc/jemalloc.h>
#if (JEMALLOC_VERSION_MAJOR == 2 && JEMALLOC_VERSION_MINOR >= 1) || (JEMALLOC_VERSION_MAJOR > 2)
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) je_malloc_usable_size(p)
#else
#error "Newer version of jemalloc required"
#endif
#elif defined(__APPLE__)
#include <malloc/malloc.h>
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) malloc_size(p)
#endif
也可以了解 tcmalloc 和 jemalloc 的實作