2011-11-24 104 views
4

可能重複:
Simple C implementation to track memory malloc/free?如何跟蹤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中釋放的內存量。)

+0

我問你爲什麼要做到這一點?這對於你自己來說更像是自測嗎?還是你試圖分析數據使用?如果你只是想跟蹤和理解內存使用情況,可以看看可免費使用的'valgrind'應用程序。 – Grambot

+2

C或C++?選一個。 –

+1

如果'malloc'失敗怎麼辦?嘗試'void * MyMalloc(int size){void * tmp = malloc(size); if(tmp)usedMemory + = size;返回tmp; }'而不是:) – pmg

回答

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); 
} 
+2

請注意,如果'malloc'返回的對齊大於'sizeof(int) '那麼這將返回未對齊的內存,並且'int'無論如何都被允許小於'size_t'。要在特定平臺上快速入侵,只需使用任何看起來合理的整數類型即可,這當然可能是「int」。 –

+0

正如史蒂夫所說 - 最好找出最大對齊方式,將*分配得更多,然後在該額外塊的開頭寫入整數。 –

+0

@SteveJessop:老實說,我不太瞭解對齊方式,所以在這方面做不到更好(我不確定)。隨意編輯這個答案,或發佈一個新的答案,所以我也可以學習對齊問題。 – Nawaz

2

在C++中,您可以保留一個全局的std::map<void*, std::size_t>來跟蹤每個分配塊的大小;您自己的分配器函數將在分配時註冊大小,並且釋放函數將刪除該條目。 (更新:或者按照鏈接的問題建議並分配更多的內存並在那裏保存大小。)

更根本的問題是,這可能只會在典型的C++程序中使用非常有限:分配主要通過兩種方式完成:1)通過明確的new表達式,其稱爲::operator new(),其依次(通常)稱爲malloc(),以及2)至std::allocator<T>::allocate(),其在許多平臺上根據::operator new()實現。

問題是,您無法控制平臺的具體細節。您可以替換全球運營商 - 使用您自己的MyMalloc(),但默認std::allocator可能直接使用malloc(),因此不會受此影響。

用於調試目的的更簡潔的方法是使用外部工具(如valgrind)來跟蹤堆使用情況。對於永久內部使用,跟蹤分配大小也會導致顯着的性能下降。

1

你可以分配內存和存儲分配的內存塊的大小(錯誤檢查略去了):

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); 
} 

這段代碼實際上保留比以存儲集團請求更多的內存k的大小通常在前四個字節中。隨後可以在釋放內存時檢索此信息。

+2

問題是,您不再返回一個良好對齊的指針,原則上導致整個地圖上的未定義行爲。 –

+0

我不明白。這原則上不應該是「僅多4字節」的分配?如果我選擇分配「char」數組並且 - 按原則 - 開始在索引5處將數據寫入該數組,則內存仍然被正確分配,不是嗎? –

+0

已分配,但未正確對齊。 –

0

您需要管理您使用指針+大小完成的所有malloc()的列表。然後,您可以在該列表中搜索大小,然後在free()中將其減小。

檢查例如在例如它們是如何做的: http://developers.sun.com/solaris/articles/lib_interposers_code.html#malloc_interposer.c

你可能有其他的可能性,以跟蹤內存,如:

統計(一個側面說明,請接受一些回答您的問題!)

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; 
}