如何跟踪malloc和免费?

时间:2011-11-24 16:07:54

标签: c

  

可能重复:
  Simple C implementation to track memory malloc/free?

我需要知道我在C程序中使用了多少内存,这里是伪代码

#include <stdio.h>

int usedMemory =0;

void *MyMalloc(int size){
 usedMemory = usedMemory +size ;
 return malloc(size);
}

void MyFree(void *pointer){
/*****************what should i write here????*************/
}
int main(int argc, char *argv[])
{
    char *temp1= (char *)MyMalloc(100);
    char *temp2= (char *)MyMalloc(100);

    /*......other operations.........*/

    MyFree(temp1);
    MyFree(temp2);

    return 0;
}

任何人都可以告诉我在MyFree方法中写什么(减少从usedMemory中释放的内存量。

5 个答案:

答案 0 :(得分:10)

你可以分配比所要求的更少的额外的字节,并将大小存储在额外的字节中,这样你就可以在MyFree函数中稍后知道大小,只需很少的计算为:

unsigned long int usedMemory = 0;

void *MyMalloc(int size)
{
  char *buffer = (char *) malloc(size + sizeof(int)); //allocate sizeof(int) extra bytes 
  if ( buffer == NULL) 
      return NULL; // no memory! 

  usedMemory += size ;      
  int *sizeBox = (int*)buffer;
  *sizeBox = size; //store the size in first sizeof(int) bytes!
  return buffer + sizeof(int); //return buffer after sizeof(int) bytes!
}

void MyFree(void *pointer)
{
   if (pointer == NULL)
       return; //no free

   char *buffer = (char*)pointer - sizeof(int); //get the start of the buffer
   int *sizeBox = (int*)buffer;
   usedMemory -= *sizeBox;
   free(buffer);
}

答案 1 :(得分:2)

在C ++中,您可以保留全局std::map<void*, std::size_t>来跟踪每个已分配块的大小;您自己的分配器函数将在分配时注册大小,并且释放函数将删除该条目。 (更新:或者按照链接的问题建议并分配更多内存并在那里保存大小。)

更基本的问题是,在典型的C ++程序中,这可能只会非常有限:分配主要以两种方式完成:1)通过显式new表达式,调用{{1} },反过来(通常)调用::operator new(),以及2)到malloc(),在许多平台上按std::allocator<T>::allocate()实现。

问题在于您无法控制平台的细节。您可以替换全局operator-new以使用您自己的::operator new(),但默认MyMalloc()可能会直接使用std::allocator,因此不会受此影响。

用于调试目的的更简洁方法是使用外部工具(如malloc())来跟踪堆使用情况。对于永久性内部使用,跟踪分配大小也会导致性能受到重大影响。

答案 2 :(得分:2)

您可以分配内存并将其大小存储在已分配的块中(为简洁起见,省略了错误检查):

unsigned int totalAlloc = 0;

void *MyAlloc(unsigned int size)
{
    void *p;
    totalAlloc += size;

    p = malloc(size + sizeof(int));
    *(int *) p = size;
    return (void *)(((int *) p) + 1)
}

void MyFree(void *ptr)
{
    ptr = (void *)(((int *) ptr) -1 );
    totalAlloc -= * (int *) ptr;
    free(ptr);
}

此代码实际上保留了比请求更多的内存,以便将块的大小存储在(通常)前四个字节中。然后,当您释放内存时,可以稍后检索此信息。

答案 3 :(得分:0)

您需要使用指针+大小管理所有malloc()的列表。然后,您可以搜索该列表中的大小,并将其减去free()。​​

在该示例中检查它们是如何做的: http://developers.sun.com/solaris/articles/lib_interposers_code.html#malloc_interposer.c

您可能还有其他跟踪记忆的可能性,例如:

(旁注,请接受您问题的一些答案!)

答案 4 :(得分:0)

你可以尝试这样的东西......我强烈建议只将其用于调试目的!

#define MAXMEMBLOCKS 10000

typedef struct {
    int size;
    void* ptr;
} memblock;

typedef struct {
    int totalSize;
    int current;
    memblock memblocks[MAXMEMBLOCKS];
} currentMemory;

currentMemory mem;

void *MyMalloc(int size) {
    if (mem.current < MAXMEMBLOCKS) {
        mem.current += size;
        mem.memblocks[mem.current].size = size;
        mem.memblocks[mem.current].ptr = malloc(size);
        return mem.memblocks[mem.current++].ptr;
    } else {
        // you needed more memblocks than estimated
        return NULL;
    }
};

int MyFree(void *pointer) {
    int i;
    for (i = 0; i < mem.current; i++) {
        if (mem.memblocks[i].ptr == pointer) {
            mem.totalSize -= mem.memblocks[i].size;
            free(mem.memblocks[i].ptr);
            mem.current--;
            return 0;
        }
    }
    // you tried to free a block wich hasn't been allocated through MyMalloc()
    return -1;
}