【发布时间】:2021-09-05 14:05:48
【问题描述】:
所以我一直在尝试在 C 中创建一个通用的递归快速排序实现。为了使其通用,我使用了一个比较函数指针。此外,由于我们可以使用 Lomuto 或 Hoare 分区,我使用一个函数指针指向两个单独的函数,一个用于每个分区。现在我只完成了 Lomuto 部分。现在当然,比较函数不是用在快速排序函数本身上,而是用在分区函数上,所以我传递函数指针。应该很简单,但我迫切需要一些帮助,因为我在尝试调用该函数时不断遇到分段错误:
quicksort_recursive(array, 0, 8, sizeof(int), &cmpnum, &partition_lomuto);
这里是比较函数:
int cmpnum(const void* s1, const void* s2)
{
int *a = (int*)s1;
int *b = (int*)s2;
if ((*a) > (*b))
return 1;
else if ((*a) < (*b))
return -1;
else
return 0;
}
这是数组:
int array[] = [3, 7, 8, 5, 2, 1, 9, 5, 4];
肇事者在这里某处:
void swap(void *a, void *b, size_t size)
{
char buffer[size];
memcpy(buffer, a, size);
memcpy(a, b, size);
memcpy(b, buffer, size);
return;
}
void *get(void *const array, size_t index, size_t size)
{
return ((char *)array) + (index * size);
}
size_t partition_lomuto(void *const array, size_t low, size_t high, size_t size, __compar_fn_t compare)
{
void *pivot = get(array, high, size);
size_t i = low;
for (size_t j = low; j <= high - 1; j++)
{
if(compare(get(array, j, size), pivot) <= 0)
{
i++;
swap(get(array, i, size), get(array, j, size), size);
}
}
swap(get(array, i + 1, size), get(array, high, size), size);
return (i + 1);
}
void quicksort_recursive(void *const array, size_t low, size_t high, size_t size, __compar_fn_t compare, size_t (*partition)(void *const array, size_t low, size_t high, size_t size, __compar_fn_t compare))
{
if (low < high)
{
size_t partition_index = partition(array, low, high, size, compare);
quicksort_recursive(array, low, partition_index - 1, size, compare, partition);
quicksort_recursive(array, low, partition_index + 1, size, compare, partition);
}
return;
}
【问题讨论】:
-
触发 seg 错误的确切代码行是什么,您还进行了哪些其他调试?在调试器中运行您的程序。它会立即为您提供 seg fault 代码行,也可用于在程序运行时跟踪程序。 How to debug small programs
-
@kaylum 我对调试非常陌生,但我会尽力而为。我的调试方法是长时间关注代码并将 printfs 放在任何地方,但都没有产生任何有意义的结果。 CLion 的调试器说(我认为)分段错误是在交换函数的第 3 行(char buffer[size];)处触发的。
-
“我对调试很不熟悉”。如果是这种情况,那么最好先暂停编码并学习有效地使用调试工具。从长远来看,这将为您节省大量时间,并且比每次都在 SO 上发布以让其他人为您调试更有效率。
-
即使对于最有经验的人来说,仅仅通过观察任何重要的代码来发现问题也很难甚至是不可能的。这就是为什么所有寻求调试帮助的 SO 问题都必须提供complete minimal reproducible example 以便任何人都可以运行和调试确切问题的主要原因之一。此外,暂停代码并不困难。您可以在 5 分钟内学会它。只需运行
break function_name
在您希望调试器停止的位置插入断点。 -
打印语句调试是一种有效的方法,如果你将它应用到这段代码中,我想你会有所启发。
标签: c algorithm sorting segmentation-fault quicksort