【问题标题】:Bug in quicksort example (K&R C book)?快速排序示例中的错误(K&R C 书)?
【发布时间】:2011-09-23 03:17:18
【问题描述】:

这种快速排序应该将“v[left]...v[right] 排序为升序”;从 K&R 的 The C Programming Language (Second Edition) 复制(没有 cmets):

void qsort(int v[], int left, int right)
{
    int i, last;
    void swap(int v[], int i, int j);

    if (left >= right)
        return;
    swap(v, left, (left + right) / 2);
    last = left;
    for (i = left+1; i <= right; i++)
        if (v[i] < v[left])
            swap(v, ++last, i);
    swap(v, left, last);
    qsort(v, left, last-1);
    qsort(v, last+1, right);
}

我认为这里有一个错误

(left + right) / 2

假设左 = INT_MAX - 1,右 = INT_MAX。由于整数溢出,这不会导致未定义的行为吗?

【问题讨论】:

标签: c integer-overflow qsort undefined-behavior


【解决方案1】:

K&R 在使用无符号和有符号参数时总是有点草率。我想使用只有 16 KB 内存的 PDP 会产生副作用。那是前一阵子修好的。目前qsort的定义是

void qsort(
   void *base,
   size_t num,
   size_t width,
   int (__cdecl *compare )(const void *, const void *) 
);

注意使用 size_t 而不是 int。当然还有 void* base 因为你不知道你在排序什么类型。

【讨论】:

  • __cdecl 疣不是标准定义的一部分。
  • 我确定这是真的,当时他们可能只有 一个 调用约定。以 two 下划线开头的关键字要少得多。让供应商让它变得复杂。必然如此,标准的有点sux。
【解决方案2】:

是的,你是对的,虽然它可能只是为了简单起见才这样写——毕竟这是一个示例,而不是生产代码。

【讨论】:

    【解决方案3】:

    您不会想象一个包含 INT_MAX 个元素的数组,是吗?

    【讨论】:

    • 假设为 32 位整数,这还不到 8 GB 的地址空间。在现代硬件上不仅仅是可行的。 :)
    • 我们可能不得不原谅 K&R 没有考虑将内存从 kB 增加到 GB。并且“640k 应该对每个人都足够了”?
    • @Bo 有 16 位的平台 ints,你知道,我很确定其中一些有超过 64Kb 的内存。 int != intptr_t.
    【解决方案4】:

    是的,你是对的。您可以使用left - (left - right) / 2 来避免溢出。

    【讨论】:

    • @Jerry / Paul:由于(right - left) == - (left - right),与此答案的表述相同。
    • @caf:啊,我没有这么想,但你是对的。我撤销我原来的评论,并为我的迟钝道歉。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-17
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 2021-09-17
    相关资源
    最近更新 更多