我的通用快速排序有什么问题?

时间:2016-03-30 13:44:49

标签: c quicksort

我正在尝试编写一个通用的快速排序:

void _qsort(void *ptr, 
        size_t lrange, 
        size_t rrange,
        size_t size,
        int (*cmp)(const void *, const void *))
{
    if (lrange < rrange) {
        size_t i, j;
        void *key;

        key = malloc(size);
        i = lrange;
        j = rrange;
        memcpy(key, ptr + i * size, size);
        while (i < j) {
            while (i < j && (*cmp)(ptr + j * size, key) > 0)
                j--;
            if (i < j) {
                memcpy(ptr + i * size, ptr + j * size, size);
                i++;
            }
            while (i < j && (*cmp)(key, ptr + i * size) > 0)
                i++;
            if (i < j) {
                memcpy(ptr + j * size, ptr + i * size, size);
                j--;
            }
        }
        memcpy(ptr + i * size, key, size);
        _qsort(ptr, lrange, i - 1, size, cmp);
        _qsort(ptr, i + 1, rrange, size, cmp);
    }
}

我在int数组上写了一个简单的测试,这是cmp函数:

int cmp(const void *x, const void *y)
{
    return *(int *)x - *(int *)y;
}

它导致核心转储,但是当我将lrange, rrange, i, j的类型从size_t更改为int时,它运行正常,我无法理解,为什么?

2 个答案:

答案 0 :(得分:3)

memcpy(key, ptr + i * size, size);

ptrvoid *,您无法使用void *指针算法,切换到标准库中的char *qsort )。

答案 1 :(得分:2)

size_t i, j;

是无符号类型。如果无符号变量的值为0,并且减去1,则该值将环绕到该无符号类型的最大可能值。

这可能发生在一行:

j--;

_qsort(ptr, lrange, i - 1, size, cmp);

当该无效值用作数组的索引时,它将导致seg-fault,因为程序无法读取超出范围的地址。

请勿使用前缀为__qsort的名称,因为这些名称是为实现而保留的。