【问题标题】:Coding realloc in C : trying to change the size of the allocation first在 C 中编码 realloc:首先尝试更改分配的大小
【发布时间】:2016-04-07 11:41:18
【问题描述】:

我正在尝试在 C 中重新编码 realloc,但我对 man 和我所做的 realloc 函数有疑问,因为它并没有完全按照 realloc 的人所说的那样做。

这是我的代码:

void *ft_realloc(void *ptr, size_t len) {
    void *dup;

    dup = ft_memalloc(len);
    if (ptr) {
        if (dup)
            ft_memcpy(dup, ptr, len);
        ft_memdel(&ptr);
    }
    return (dup);
}

但是那个人说:

realloc() 函数尝试将 ptr 指向的分配大小更改为 size,并返回 ptr。如果没有足够的空间来扩大 ptr 指向的内存分配,realloc() 会创建一个新分配,复制 ptr 指向的旧数据以适应新分配,释放旧分配,然后 >返回一个指向分配内存的指针。

问题是,我不知道如何“尝试更改 ptr 指向的分配的大小”(最好我想在不执行 strlen 的情况下执行 int,但通过将 ptr 的大小作为参数发送我的 realloc 函数)。我的代码中缺少这部分。 你能帮我吗? 最重要的是,如果 opensource link 这对我来说很奇怪,我看不到任何尝试“将大小 [...] 更改为 ptr”!

【问题讨论】:

标签: c heap-memory realloc


【解决方案1】:

您需要一个 ft_memsize(ptr) 函数来获取分配的大小,以便将较小的那个和 len 复制到新分配的块。

没有这样的功能,你只能处理这些琐碎的情况:

  • ft_realloc(NULL, size);:返回malloc(size)。
  • ft_realloc(ptr, 0);: free(ptr); 并返回NULL。

对于所有其他情况,您只会失败并返回 NULL。

如果你有,就用这个:

void *ft_realloc(void *ptr, size_t len) {
    void *dup = NULL;
    size_t size = ptr ? ft_memsize(ptr) : 0;

    if (len == size)
        return ptr;

    if (len)
        dup = ft_memalloc(len);

    if (ptr && dup) {
        ft_memcpy(dup, ptr, size < len ? size : len);
        ft_memdel(&ptr);
    }
    return dup;
}

如果你自己实现了ft_memalloc和朋友,你知道堆管理的细节,你可以尝试修补内部堆结构,而不是分配一个新的块。这就是标准的意思,试图将 ptr 指向的分配大小更改为 size:

  • 如果重新分配到相同的大小,您可以只返回相同的块。
  • 如果重新分配到较小的大小,您可以拆分块并在 ptr 的新收缩块的末尾创建一个空闲块。如果没有足够的空间来分割块,要么创建一个新的更小的块,要么返回当前的ptr。
  • 如果重新分配到更大的大小,并且内存中的下一个块是空闲的,您可以将ptr 的当前块与其相邻块合并并返回相同的指针。

【讨论】:

    【解决方案2】:

    通常的堆实现,如dlmalloc、ptmalloc、jemalloc、tcmalloc 等...以块大小组维护内存。

    因此,当调用realloc 时,如果请求的大小大于/小于块大小边界,它会分配一个新块,复制/释放旧块,并返回新块。否则,它只能返回传入的块,速度明显更快。

    wikipedia 页面包含更多信息。

    【讨论】:

    • 这比我预期的要复杂得多!非常有用,谢谢大家
    【解决方案3】:

    内存管理系统跟踪分配的大小;这就是它如何判断对realloc 的调用是否正在尝试更改大小(以及它如何执行free() 之类的操作)。你也需要这样做。

    【讨论】:

      猜你喜欢
      • 2015-09-02
      • 1970-01-01
      • 1970-01-01
      • 2013-06-02
      • 1970-01-01
      • 2017-01-25
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多