有一个malloc变种,在调用`free()`时清零块吗?

我想在系统范围内replace标准的malloc(通过LD_PRELOAD或者只是replace已安装的libc),将所有可能被释放的块清空。 有谁知道现有的解决scheme?

零堆在堆的未使用部分将使压缩它通过zramconfiguration更有效。 由于我需要比CPU更多的RAM,增加的CPU使用率不成问题。

您可以修改系统上的C库。 我不认为你会发现一个修改的C库做的内存分配方式,因为它是非标准的。 但修改听起来相对容易。 看看你的C库的实现,你可以用free + memset的包装来代替免费的实现。

以防万一遇到类似的问题,下面是eglibc 2.17的补丁。

 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -1424,10 +1424,16 @@ #define first(b) ((b)->fd) #define last(b) ((b)->bk) +#define zero_sizes(P) { \ + P->size = 0; \ + P->prev_size = 0; \ +} + /* Take a chunk off a bin list */ #define unlink(P, BK, FD) { \ FD = P->fd; \ BK = P->bk; \ + P->bk = 0; P->fd = 0; \ if (__builtin_expect (FD->bk != P || BK->fd != P, 0)) \ malloc_printerr (check_action, "corrupted double-linked list", P); \ else { \ @@ -1449,9 +1455,11 @@ } else { \ P->fd_nextsize->bk_nextsize = P->bk_nextsize; \ P->bk_nextsize->fd_nextsize = P->fd_nextsize; \ } \ + P->fd_nextsize = 0; \ + P->bk_nextsize = 0; \ } \ } \ } /* @@ -1878,8 +1886,10 @@ static int perturb_byte; -#define alloc_perturb(p, n) memset (p, (perturb_byte ^ 0xff) & 0xff, n) -#define free_perturb(p, n) memset (p, perturb_byte & 0xff, n) +#define alloc_perturb(p, n) do {} while(0) +#define free_perturb(p, n) memset (p, 0, n) /* ------------------- Support for multiple arenas -------------------- */ @@ -3809,8 +3819,7 @@ } } - if (__builtin_expect (perturb_byte, 0)) - free_perturb (chunk2mem(p), size - 2 * SIZE_SZ); + free_perturb (chunk2mem(p), size - 2 * SIZE_SZ); set_fastchunks(av); unsigned int idx = fastbin_index(size); @@ -3892,13 +3901,13 @@ goto errout; } - if (__builtin_expect (perturb_byte, 0)) - free_perturb (chunk2mem(p), size - 2 * SIZE_SZ); + free_perturb (chunk2mem(p), size - 2 * SIZE_SZ); /* consolidate backward */ if (!prev_inuse(p)) { prevsize = p->prev_size; size += prevsize; + unlink_free(p); p = chunk_at_offset(p, -((long) prevsize)); unlink(p, bck, fwd); } @@ -3910,6 +3921,7 @@ /* consolidate forward */ if (!nextinuse) { unlink(nextchunk, bck, fwd); + zero_sizes(nextchunk); size += nextsize; } else clear_inuse_bit_at_offset(nextchunk, 0); @@ -4069,6 +4081,7 @@ if (!prev_inuse(p)) { prevsize = p->prev_size; size += prevsize; + zero_sizes(p); p = chunk_at_offset(p, -((long) prevsize)); unlink(p, bck, fwd); } @@ -4079,6 +4092,7 @@ if (!nextinuse) { size += nextsize; unlink(nextchunk, bck, fwd); + zero_sizes(nextchunk); } else clear_inuse_bit_at_offset(nextchunk, 0); 

为什么不写你自己的free_zero函数?

 void free_zero(void *p, size_t n) { volatile unsigned char *zp = p; if (!p) return; while (n--) { *zp++ = 0; } free(p); }