glibc malloc()字节总数

Total glibc malloc() bytes

本文关键字:字节 malloc glibc      更新时间:2023-10-16

如何获得程序中malloc()'d的总字节数(假设我使用glibc运行)?我不想看到程序占用了多少内存,我想看到我分配了多少内存。下面是一个示例程序,其中这些数字将非常不同。

#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
int main() {
    vector<void *> p;
    printf("Allocating...n");
    for (size_t i = 0; i < 1024 * 1024 * 10; ++i) {
        p.push_back(malloc(1024));
        memset(*p.rbegin(), 0, 1024);
    }
    printf("Press return to continue...n");
    getchar();
    printf("Freeing all but last...n");
    for (size_t i = 0; i < p.size() - 1; ++i)
        free(p[i]);
    printf("Press return to continue...n");
    getchar();
    // UNTIL THIS FREE, TOP WOULD SHOW THIS PROGRAM TAKES 16G,
    // BUT THE TOTAL MALLOC() SIZE IS MUCH LESS.
    printf("Freeing last...n");
    free(*p.rbegin()); 
    printf("Press return to continue...n");
    getchar();
}

我知道这可以通过LD_PRELOAD或通过拥有自己的mallocfree函数来实现,但是是否有更简单的方法来获得malloc()总数?

各种语言标准规定:

没有独立于平台的方法来获取这些信息。malloc的不同实现可能提供此信息,但它将以非标准的方式提供。

Glibc提供:

  • 您可以使用__malloc_hook特性来编写一个钩子,该钩子计算已分配的内存数量。

  • 还有mallinfo(),它应该提供一些关于已分配内存的信息。

创建一个全局变量和自己的malloc()函数

static size_t count;
void *malloc_ex(size_t n)
{
    count+=n;
    return malloc(n);
}

那么任何时候你都可以通过查看count变量来知道分配了多少字节。

全局变量被编译器初始化为0,所以没有问题。并且请不要将#undef malloc#define更改为malloc_ex(),否则将为未定义行为。

您应该定义两个函数,并分配额外的空间来跟踪每次调用自定义分配器函数所分配的内存。

//Space to store the size of an allocation
struct _room {
    size_t sz;  //Chunk size     
    char padding[16-(sizeof(size_t) % 16)]; //Force 16-byte alignment   
}
//A global variable to keep track of the total amount of memory allocated (except the extra space of storing chunk sizes
static size_t TOTAL = 0;

//Custom allocator
void *mymalloc(size_t sz) {
    //Allocate memory plus room for storing the chunk size. We'll need it later in 
    //myfree() to appropriately decrement TOTAL.
    struct _room *r = (struct _room *) malloc(sz + sizeof(struct _room));
    r->sz = sz;
    TOTAL += sz; //keep track of user allocated memory
    return (void *) (r+1); //Pointer to usable memory
}
void myfree(void *m) {
    //Point to the register with chunk size, given the memory pointer returned my mymalloc()
    struct _room *r = ((struct _room *) m) - 1;
    TOTAL -= r->sz; //Update total
    free((void*)r); //Free all memory: room + user memory
}