2016-01-29 71 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