Lua処理系コード読み(6) luaM_realloc_
lmem.c
/* ** generic allocation routine. */ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { global_State *g = G(L); lua_assert((osize == 0) == (block == NULL)); block = (*g->frealloc)(g->ud, block, osize, nsize); if (block == NULL && nsize > 0) luaD_throw(L, LUA_ERRMEM); lua_assert((nsize == 0) == (block == NULL)); g->totalbytes = (g->totalbytes - osize) + nsize; return block; }
allocとfreeはこの関数経由で行う。
man realloc
- 書式
- void *realloc(void *ptr, size_t size);
- 説明
- realloc() は、ポインタ ptr が示すメモリブロックのサイズを変更して size バイトにする。新旧 のサイズのうち、小さいほうのブロックに含まれる内容は変更されない。新しく割り当てられたメモ リ の 内容は初期化されない。 size がどの値であっても、 ptr が NULL の場合には malloc(size) と等価である。 size が 0 で ptr が NULL でない場合には、 free(ptr) と等価である。 ptr が NULL 以外の場合、 ptr は以前に呼び出された malloc(), calloc(), realloc() のいずれかが返し た値でなければならない。 ptr が指す領域が移動されていた場合は free(ptr) が実行される。
- 返り値
- realloc() は新たに割り当てられたメモリへのポインタを返す。これはあらゆる種類の変数に対応で き るようにアラインメントされており、 ptr とは異なることもある。割り当て要求に失敗した場合 は NULL が返る。 size が 0 の場合には、NULL もしくは free() に渡すことができるポインタが返 る 。 realloc() が失敗した場合には、元のブロックは変更されない。つまり、解放されたり移動さ れたりはしない。
問題ないというのはわかるんだけど何故なのかよく知らない。一つのところだけ通すから
g->totalbytes = (g->totalbytes - osize) + nsize;
みたいな処理が一箇所で済んで楽って話とかかな。
lmem.h
#define luaM_reallocv(L,b,on,n,e) \ ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ luaM_toobig(L)) #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) #define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) #define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) #define luaM_newvector(L,n,t) \ cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) #define luaM_reallocvector(L, v,oldn,n,t) \ ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
マクロなどでmalloc、freeなどを定義。