チャンクをビンから削除するための unlink() みたいなマクロだけでなく、チャンクのリスト走査をしたり、属性情報を取得するためのマクロもあります。
以下の malloc.c のソース箇所は、チャンクに関するマクロを網羅しています。
malloc.c(https://github.com/MacKomatsu/glibc/blob/release/2.27/master/malloc/malloc.c).
1245 /* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */ 1246 #define PREV_INUSE 0x1 1247 1248 /* extract inuse bit of previous chunk */ 1249 #define prev_inuse(p) ((p)->mchunk_size & PREV_INUSE) 1250 1251 1252 /* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */ 1253 #define IS_MMAPPED 0x2 1254 1255 /* check for mmap()'ed chunk */ 1256 #define chunk_is_mmapped(p) ((p)->mchunk_size & IS_MMAPPED) 1257 1258 1259 /* size field is or'ed with NON_MAIN_ARENA if the chunk was obtained 1260 from a non-main arena. This is only set immediately before handing 1261 the chunk to the user, if necessary. */ 1262 #define NON_MAIN_ARENA 0x4 1263 1264 /* Check for chunk from main arena. */ 1265 #define chunk_main_arena(p) (((p)->mchunk_size & NON_MAIN_ARENA) == 0) 1266 1267 /* Mark a chunk as not being on the main arena. */ 1268 #define set_non_main_arena(p) ((p)->mchunk_size |= NON_MAIN_ARENA) 1269 1270 1271 /* 1272 Bits to mask off when extracting size 1273 1274 Note: IS_MMAPPED is intentionally not masked off from size field in 1275 macros for which mmapped chunks should never be seen. This should 1276 cause helpful core dumps to occur if it is tried by accident by 1277 people extending or adapting this malloc. 1278 */ 1279 #define SIZE_BITS (PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) 1280 1281 /* Get size, ignoring use bits */ 1282 #define chunksize(p) (chunksize_nomask (p) & ~(SIZE_BITS)) 1283 1284 /* Like chunksize, but do not mask SIZE_BITS. */ 1285 #define chunksize_nomask(p) ((p)->mchunk_size) 1286 1287 /* Ptr to next physical malloc_chunk. */ 1288 #define next_chunk(p) ((mchunkptr) (((char *) (p)) + chunksize (p))) 1289 1290 /* Size of the chunk below P. Only valid if prev_inuse (P). */ 1291 #define prev_size(p) ((p)->mchunk_prev_size) 1292 1293 /* Set the size of the chunk below P. Only valid if prev_inuse (P). */ 1294 #define set_prev_size(p, sz) ((p)->mchunk_prev_size = (sz)) 1295 1296 /* Ptr to previous physical malloc_chunk. Only valid if prev_inuse (P). */ 1297 #define prev_chunk(p) ((mchunkptr) (((char *) (p)) - prev_size (p))) 1298 1299 /* Treat space at ptr + offset as a chunk */ 1300 #define chunk_at_offset(p, s) ((mchunkptr) (((char *) (p)) + (s))) 1301 1302 /* extract p's inuse bit */ 1303 #define inuse(p) \ 1304 ((((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size) & PREV_INUSE) 1305 1306 /* set/clear chunk as being inuse without otherwise disturbing */ 1307 #define set_inuse(p) \ 1308 ((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size |= PREV_INUSE 1309 1310 #define clear_inuse(p) \ 1311 ((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size &= ~(PREV_INUSE) 1312 1313 1314 /* check/set/clear inuse bits in known places */ 1315 #define inuse_bit_at_offset(p, s) \ 1316 (((mchunkptr) (((char *) (p)) + (s)))->mchunk_size & PREV_INUSE) 1317 1318 #define set_inuse_bit_at_offset(p, s) \ 1319 (((mchunkptr) (((char *) (p)) + (s)))->mchunk_size |= PREV_INUSE) 1320 1321 #define clear_inuse_bit_at_offset(p, s) \ 1322 (((mchunkptr) (((char *) (p)) + (s)))->mchunk_size &= ~(PREV_INUSE)) 1323 1324 1325 /* Set size at head, without disturbing its use bit */ 1326 #define set_head_size(p, s) ((p)->mchunk_size = (((p)->mchunk_size & SIZE_BITS) | (s))) 1327 1328 /* Set size/use field */ 1329 #define set_head(p, s) ((p)->mchunk_size = (s)) 1330 1331 /* Set size at footer (only when chunk is not in use) */ 1332 #define set_foot(p, s) (((mchunkptr) ((char *) (p) + (s)))->mchunk_prev_size = (s))
この中で重要なのは set_head() と set_foot() マクロです。
チャンクのヘッダーとフッターを設定しています。
チャンクのヘッダーとは use ビットやサイズ「 mchunk_size 」のことでして、このヘッダーから次のチャンクのアドレスを割り出すことができます。
1328 /* Set size/use field */ 1329 #define set_head(p, s) ((p)->mchunk_size = (s))
フッターはフリーチャンクで前のチャンクのサイズのことです。
1331 /* Set size at footer (only when chunk is not in use) */ 1332 #define set_foot(p, s) (((mchunkptr) ((char *) (p) + (s)))->mchunk_prev_size = (s))
フッター「 mchunk_prev_size 」を設定することでチャンクが使われていない事が判別できます。
Copyright 2018-2019, by Masaki Komatsu