【问题标题】:Why realloc() is so badly designed? [closed]为什么 realloc() 设计得如此糟糕? [关闭]
【发布时间】:2015-05-03 18:47:47
【问题描述】:

Herb Sutter 和 Andrei Alexandrescu 所著的“C++ 编码标准 101 条规则、指南和最佳实践”一书第 5 条说

赋予一个实体一项具有凝聚力的责任。

一次只关注一件事:更喜欢给每个实体(变量, 类、函数、命名空间、模块、库)一个定义明确的 责任。随着实体的成长,其责任范围 自然增加,但其责任不应分散

书中还给出了 C 的 realloc() 函数的例子。

在标准 C 中,realloc 是一个臭名昭著的糟糕设计示例。它必须做太多的事情:如果传递 NULL,则分配内存,如果传递它,则释放它 传递了一个零大小,如果可以的话,重新分配它,或者移动内存 如果它不能。它不容易扩展。它被广泛观看 作为一种短视的设计失败。

是的,正如我们所知,realloc() 也可用于释放内存。另见this

但我的问题是:

1) 为什么设计不好?为什么它被设计用于执行多个任务?

2) 为什么它不可扩展?

谢谢

【问题讨论】:

  • 在这种情况下可扩展是什么意思?
  • 顺便说一下,我不确定你会得到一个有用的答案。在计算历史上有数百个设计不完美的例子。为什么选择这个?
  • 我不会说它设计的糟糕,只是它可以做太多的事情,而不是遵循只做一件事然后去做好 原则。至于为什么,我只能猜测是允许以realloc() 的形式实现malloc()free()(但这只是猜测)。
  • 有人可以将此标记为 Alexandrescu 的基于意见的。 C++ 人不能太频繁地忍受非 ++ 方式(c)(tm)方式。说真的,realloc 是一个通用接口,可以处理任何有效的指针 NULL。如果他们提出这个问题,他们应该考虑在 realloc 的背景下 malloc/free 无用。 Free() 作为通用的单参数析构函数很有用,而 malloc 只是一种方便,有人会注意到。

标签: c++ c coding-style realloc


【解决方案1】:
  1. 因为检查是否可以分配内存然后实际分配它涉及一些常见的步骤,如果单独执行这些步骤将需要重新执行(因此更慢)。

    此外,将空闲操作与分配操作相结合不仅可以更快,而且还可以分配内存,否则这些内存可能无法在单独的连续位置使用。
    (想象一下分配 768 MB 的内存,然后在 1.5 GB 的机器上请求 1 GB...)

  2. 因为它是为 C 而不是 C++ 设计的。

【讨论】:

  • 换句话说,这不是一个糟糕的设计,它是一个不雅的设计,性能优势证明了它的合理性。 (就像零拷贝 I/O 证明了不优雅地遵循所有 ISO 层的设计)
  • 关于结合释放和分配,您可以将最小粒度分配大小添加到好处列表中,允许访问实际上已经分配的内存。例如,当 realloc for 和 20 字节的初始请求增加到 50 或 100 等时,最小 128 字节的块大小几乎不需要做任何事情。
  • @BenVoigt:realloc() 函数无法分离一些重要的用例,因此最终对于其中任何一个都不是最佳的。例如,有代码为对象过度分配存储空间的情况并不少见,这些对象的确切总大小可以有界,但直到它们被构造后才确切知道,然后想要调整分配。在这种情况下,如果可能的话,拥有一个 realloc() 版本会很有帮助,它会缩小分配而不移动它(或使现有指针无效),否则什么都不做。但是,Realloc 无法做到这一点。
猜你喜欢
  • 2010-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-10
  • 1970-01-01
  • 1970-01-01
  • 2010-11-19
相关资源
最近更新 更多