快速排序示例(K&RC 书)中的错误?
此快速排序应该将“v[left]...v[right] 排序为递增顺序”;复制(无注释)自 K&R 的《C 编程语言》(第二版):
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 = INT_MAX - 1 且 right = INT_MAX 存在错误
(left + right) / 2
。这不会导致由于整数溢出而导致未定义的行为吗?
This quicksort is supposed to sort "v[left]...v[right] into increasing order"; copied (without comments) from The C Programming Language by K&R (Second Edition):
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);
}
I think there's a bug at
(left + right) / 2
Suppose left = INT_MAX - 1 and right = INT_MAX. Wouldn't this result in undefined behavior due to integer overflow?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,你说得对。您可以使用
left - (left - right) / 2
来避免溢出。Yes, you're right. You can use
left - (left - right) / 2
to avoid overflows.您不会想象一个具有
INT_MAX
个元素的数组,对吗?You aren't imagining an array with
INT_MAX
number of elements, are you?是的,你是对的,尽管它可能只是为了简单起见而这样写——毕竟它是一个示例,而不是生产代码。
Yes, you're right, although it's possibly just written that way for simplicity -- it's an example after all, not production code.
K&R 在使用无符号与有符号参数方面总是有点草率。我认为使用只有 16 KB 内存的 PDP 会产生副作用。不久前已经修复了。 qsort的当前定义是
注意使用size_t而不是int。当然还有 void* base 因为你不知道你要排序的类型。
K&R was always a bit sloppy with their use of unsigned vs signed arguments. Side effect of working with a PDP that had only 16 kilobytes of memory I suppose. That's been fixed a while ago. The current definition of qsort is
Note the use of size_t instead of int. And of course void* base since you don't know what kind of type you are sorting.