2016-01-29 55 views
-5

我想更改malloc()函數calloc(),但我很困惑:我怎麼能在這段代碼中做到這一點?calloc()函數,而不是malloc()

void *mymalloc(size_t len) 
{ 

    void *buf; 
    size_t pages = (len & PAGE_MASK) + 2; 
    size_t offset = PAGE_SIZE - (len & ~PAGE_MASK); 

    if(offset < sizeof(size_t)) 
    { 
     pages++; 
     offset += PAGE_SIZE; 
    } 

    if((buf = mmap(NULL, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE, 
        MAP_PRIVATE | MAP_ANONYMOUS, 0, 0)) == -1) 
    { 
     perror("mymalloc/mmap"); 
     exit(1); 
    } 
    *(size_t *)buf = len; 
    *(size_t *)(buf+offset+len) = len; 

    if(mprotect(buf+offset+len, PAGE_SIZE, PROT_NONE) == -1) 
    { 
     perror("mymalloc/mprotect"); 
     exit(1); 
    } 

    return buf+offset; 
} 
+1

現在你的代碼中沒有'malloc()'。你在問什麼? – wallyk

+0

那裏沒有'malloc()';只有一個'mymalloc()'。據推測,你需要一個調用'mymalloc()'的'mycalloc()',然後將空間清零。你還必須考慮'malloc()'帶一個參數,'calloc()'帶兩個必須相乘以產生請求的大小。 –

+0

http://pubs.opengroup.org/onlinepubs/009695399/functions/mmap.html首次谷歌搜索結果 – khuderm

回答

2

calloc()是有效地只是malloc()memset()爲零。

假設你想mycalloc()來補充你的mymalloc()

void *mymalloc(size_t bytes) 
{ 
    ... 
    return(ptr); 
} 

你會得到:

void *mycalloc(size_t bytes, size_t n) 
{ 
    size_t total_bytes = bytes * n; 
    void *ptr = mymalloc(total_bytes); 
    memset(ptr, 0, total_bytes); 
    return(ptr); 
} 

你要添加檢查乘法溢出和mymalloc() NULL回報。

+1

您忘記確保乘法不會溢出。 – Deduplicator

+0

@Deduplicator我想給OP留下一些* *來弄清楚...... [不,我沒有忘記。 ;-)] –

+2

如果你的目標環境是Linux,你甚至不需要memset,MAP_ANONYMOUS頁面來zerod。 –

0

當你有這樣的問題,經常檢查手冊頁:

  • 的malloc:

void *malloc(size_t size);()函數分配size個字節,並返回一個指針 分配的內存中的malloc 。內存未初始化。如果大小爲0,則 ,則malloc()返回NULL,或者返回一個可以在以後成功傳遞給free()的唯一指針值。

  • 釋放calloc:

void *calloc(size_t nmemb, size_t size);的釋放calloc()函數 爲大小的nmemb個元素的數組字節每 指針返回到所分配的存儲器中分配內存。內存設置爲 零。如果nmemb或size是0,那麼calloc()返回NULL或一個可以稍後成功傳遞給free()的唯一指針值。

不同之處在於calloc還初始化分配的內存塊爲零。

+0

注意:第二個區別是,calloc()可以處理分配像'calloc(SIZE_MAX/8,16)',而'malloc()'不能。在分段架構上很有用。 – chux