在使用malloc和realloc之间是否有性能差异?

um6iljoc  于 2023-08-03  发布在  其他
关注(0)|答案(4)|浏览(166)

我有这个功能:

int program_inc_capacity(Program *program)
{
    Instruction *v_old = program->v;

    size_t capacity_new = 2 * program->capacity;

    program->v = (Instruction *)malloc(capacity_new * sizeof(Instruction));
    if (program->v == NULL)
        return 0;

    for (size_t i = 0; i < program->size; i++)
    {
        program->v[i] = v_old[i];
    }

    free(v_old);

    program->capacity = capacity_new;

    return 1;
}

字符串
当以前分配给program->v的内存不够时,我调用上面的函数。因此,我通过malloc重新分配整个内存块,使其加倍。
我没有使用这种方法,而是考虑使用realloc()。因此代码看起来像这样:

int program_inc_capacity(Program *program)
{
    Instruction *v_old = program->v;

    size_t capacity_new = 2 * program->capacity;

    Instruction *temp = (Instruction *)realloc(v_old, capacity_new * sizeof(Instruction));
    if (temp == NULL) {
        printf("Memory reallocation failed!\n");
        free(v_old);  // Free the original memory
        return 1;
    } else {
        v_old = temp;  // Update the pointer with the new memory location
    }

    for (size_t i = 0; i < program->size; i++)
    {
        program->v[i] = v_old[i];
    }

    free(v_old);

    program->capacity = capacity_new;

    return 1;
}


所以,我的问题是:是否存在任何性能差异?在哪种情况下,第一种方法比第二种方法更好,反之亦然?我还读到过多次使用realloc会导致内存碎片。

kcrjzv8t

kcrjzv8t1#

您对realloc()的使用似乎有很多错误

  • 你为什么对成功如此着迷?
  • 您尚未更换program->v
  • realloc()为您复制数据-如果重新分配成功,您不得访问旧指针值。
  • 该函数始终返回1。

我建议这样简单地重写:

int program_inc_capacity(Program *program)
{
    size_t capacity_new = 2 * program->capacity;
    Instruction *temp = realloc(program->v, capacity_new * sizeof(Instruction));
    if (temp == NULL) {
        printf("Memory reallocation failed!\n");
        return 1;
    }
    program->v = temp;
    program->capacity = capacity_new;
    return 0;
}

字符串

v1uwarro

v1uwarro2#

是否存在任何性能差异?
是的,这可能是一个很大的差异。

  • 使用malloc时,您必须将数据从旧内存复制到新内存。
  • 使用realloc时,realloc可能能够就地增加分配的内存。然后,返回的指针将指向与原始指针相同的地址。这样就不需要复制任何数据。

注意:在使用realloc的实现中,您似乎复制了旧的数据和free旧的指针。这是不需要的。realloc可以为您完成此操作。它不仅是不需要的:旧的指针被认为是“悬空的”,你不应该取消引用或free它所指向的。

ulydmbyx

ulydmbyx3#

是的,性能可能会有差异。
如果realloc()能够就地调整大小,则不需要复制内容。这可以减少瞬时存储器使用和指令计数。
即使在需要移动时,realloc()也可以使用您无法使用的技术(例如重新Map虚拟内存)来降低其成本。
但是您的代码严重损坏,正如Weather Vane's answer所解释的那样。在开始比较性能之前,您需要使其“正确”。

tjjdgumg

tjjdgumg4#

是的,有一个(小)区别:
realloc(3)只是在堆上没有空间扩展已经分配的内存时将内存重新分配到不同的位置,因此当不需要重新分配时,它的运行速度比malloc(3)快。
此外,当重新分配到不同的位置时,必须将先前分配的块的内容复制到新的位置,因此如果您不需要复制原始内容,则会做额外的工作。

相关问题