C语言中Realloc的实现

4
int getmin(int a, int b)
{
    return a<b?a:b;
}


void *reallocation(void *ptr, size_t size) //size_t in bytes
{

    void *newptr;


    int msize;
    msize = getsize(ptr);

    msize = getmin(msize, size);

        printf("msize = %d", msize);

    newptr = malloc(size);
    newptr = memcpy(newptr, ptr, msize);
    free(ptr);


    return newptr;

}

我已经实现了自己的realloc函数,但是为了使用malloc函数分配内存时获取分配的内存大小(然而我知道C语言中没有这种方法)。

我的重新分配函数在我的系统上运行良好。如何获取malloc()分配的内存大小。

如果之前分配的内存大小大于新需求的内存大小,我们能否进行原地重新分配?


1
你的总体目标是什么?你只是在重写realloc还是试图创建整套内存分配例程? - Gort the Robot
3个回答

14

没有一种可移植的方法可以获取由malloc()分配的内存大小。

然而,我们总是可以像这样做来模拟你想要的功能。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void myfree(void * p) {
    size_t * in = p;
    if (in) {
        --in; free(in);
    }
}

void * mymalloc(size_t n) {
    size_t * result = malloc(n + sizeof(size_t));
    if (result) { *result = n; ++result; memset(result,0,n); }
    return result;
}

size_t getsize(void * p) {
    size_t * in = p;
    if (in) { --in; return *in; }
    return -1;
}

#define malloc(_x) mymalloc((_x))
#define free(_x) myfree((_x))

void *reallocation(void *ptr,size_t size) {
    void *newptr;
    int msize;
    msize = getsize(ptr);
    printf("msize=%d\n", msize);
    if (size <= msize)
        return ptr;
    newptr = malloc(size);
    memcpy(newptr, ptr, msize);
    free(ptr);
    return newptr;
}
int main() {
    char * aa = malloc(50);
    char * bb ;
    printf("aa size is %d\n",getsize(aa));
    strcpy(aa,"my cookie");
    bb = reallocation(aa,100);
    printf("bb size is %d\n",getsize(bb));
    printf("<%s>\n",bb);
    free(bb);
}

3
如果返回类型声明为无符号的话,getsize不应该返回-1。 - Jan Turoň

3

malloc 不会初始化内存为零。(等价的是 calloc。)如果您看到的是零,那是偶然发生的。

我认为库版本的 realloc 使用堆中不直接可用的长度信息。(并且它可能高估了原始分配,这意味着当使用 realloc 扩展分配时可能会复制一些额外的内存。通常没有影响。)

realloc 在缩小分配时很可能不会进行复制。

另外,我应该指出,在某些情况下,即使 realloc 增加了大小,您也不必进行复制,例如,如果堆中的下一个块是空闲的。


出现这种情况可能并非意外地被设置为零,大多数操作系统出于安全考虑会将新分配的页面填充为零。 - JustSid
1
@JustSid 是的,但你不知道这是一个新分配的页面。它可能是之前被分配和释放的内存。 - Gort the Robot
在g++中尝试这段有趣的代码:int *ip=new int;*ip=42;delete ip;int *ip2 = new int; std::out << *ip2 << endl;。它会愉快地输出“42”。 - Gort the Robot
我从未说过是否获得新页面是确定性的。我只是认为值得一提的是,在某些情况下它不会意外地为零。 - JustSid

1

由malloc分配的内存会被初始化为零,因此我正在检查该条件。

这是不正确的。从草案中可以看出:

描述

2 malloc函数分配一个大小由size指定且值不确定的对象的空间。

您需要修复getsize

我的重新分配函数运行良好。

您甚至没有修复对齐方式--它可能会对某些类型失败。请阅读this SO问题。

如果先前分配的内存大小大于所需的新内存大小,我们也可以进行原地重新分配吗?

什么是原地重新分配?这不应该是一个简单的无操作吗?


我们如何修复对齐方式? - Luv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接