如何解决C 使用 qsort
你有什么问题?
我正在尝试使用 C 中的 qsort
函数对二维整数数组进行排序,但我
出现分段错误。
当我使用以下命令编译它时:
gcc -g -lm -Werror -Wfatal-errors -Wall -Wextra -Wuninitialized -fsanitize=address -pedantic -Wshadow -std=c99 Test2.c
然后执行它,我收到此错误消息:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==347270==ERROR: AddressSanitizer: SEGV on unknown address 0x00147fff8c06 (pc 0x556f9e44d2bb bp 0x7ffe9684a5f0 sp 0x7ffe9684a5d0 T0)
==347270==The signal is caused by a READ memory access.
#0 0x556f9e44d2bb in compare /windows/Programming/C/Random_Stuff/Test2.c:8
#1 0x7f17aa2718d7 in msort_with_tmp.part.0 (/usr/lib/libc.so.6+0x3e8d7)
#2 0x7f17aa2716b4 in msort_with_tmp.part.0 (/usr/lib/libc.so.6+0x3e6b4)
#3 0x7f17aa2716b4 in msort_with_tmp.part.0 (/usr/lib/libc.so.6+0x3e6b4)
#4 0x7f17aa271a79 in __qsort_r (/usr/lib/libc.so.6+0x3ea79)
#5 0x556f9e44d657 in main /windows/Programming/C/Random_Stuff/Test2.c:64
#6 0x7f17aa25ab24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
#7 0x556f9e44d13d in _start (/windows/Programming/C/Random_Stuff/a.out+0x113d)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /windows/Programming/C/Random_Stuff/Test2.c:8 in compare
==347270==ABORTING
提示:请不要被目录名称 windows
激怒,我正在
linux。
代码
简化示例
在下面的代码中,我创建了一个 10x10 的数组,如下所示:
[ 0,1,2,3,4,5,6,7,8,9]
[10,11,12,13,14,15,16,17,18,19]
[20,21,22,23,24,25,26,27,28,29]
[30,31,32,33,34,35,36,37,38,39]
[40,41,42,43,44,45,46,47,48,49]
[50,51,52,53,54,55,56,57,58,59]
[60,61,62,63,64,65,66,67,68,69]
[70,71,72,73,74,75,76,77,78,79]
[80,81,82,83,84,85,86,87,88,89]
[90,91,92,93,94,95,96,97,98,99]
现在我想根据每个子数组的特定索引以“第一个”数组的相反顺序对这些“行”进行排序。 所以它最终应该是这样的:
[90,99]
[80,89]
[70,79]
[60,69]
[50,59]
[40,49]
[30,39]
[20,29]
[10,19]
[ 0,9]
原始案例
在我原来的情况下,我有这样的事情:
[8,20,0]
[13,1]
[8,30,2]
[8,3]
[8,10,4]
[8,5]
[13,6]
[13,7]
[8,8]
[8,9]
[13,10]
[8,11]
[8,12]
[8,13]
[13,14]
[9,15]
[8,16]
现在我想根据每个“子数组”的第四个值对这些“子数组”进行排序 子数组,所以它应该是这样的:
[8,13]
[8,16]
[8,5]
[8,4]
[13,6]
[8,10]
[13,12]
[13,14]
[8,0]
[8,11]
[13,2]
[9,15]
你尝试了什么?
我看到了这个帖子: Sorting a 2D array with qsort 但是如果我将它与 发布。
#include <stdio.h>
#include <stdlib.h>
int compare(const void * a,const void * b)
{
// "const void * a" points to "&nums[x]",right?
unsigned short val1 = (*(unsigned short **) a) [3];
unsigned short val2 = (*(unsigned short **) b) [3];
if (val1 < val2)
return 1;
else if (val1 == val2)
return 0;
return -1;
}
int main()
{
unsigned short ** nums;
unsigned short num;
unsigned short index;
unsigned short index2;
const unsigned short length = 10;
const unsigned short sub_length = 10;
/* -----------------
* Preparations
* ----------------- */
nums = malloc(sizeof(unsigned short *) * length);
num = 0;
if (nums == NULL)
return EXIT_FAILURE;
/* ------------
* Filling
* ------------ */
for (index = 0; index < length; index++)
{
nums [index] = malloc(sizeof(unsigned short) * sub_length);
if (nums [index] == NULL)
return EXIT_FAILURE;
// Fill each subarray with random nums
for (index2 = 0; index2 < sub_length; index2++)
nums [index][index2] = num++;
}
// "Before" output
printf("Before:\n");
for (index = 0; index < length; index++)
{
printf("[");
for (index2 = 0; index2 < sub_length - 1; index2++)
printf("%2hu,",nums [index][index2]);
printf("%2hu]\n",nums [index][sub_length - 1]);
}
// ================
// What am I doing wrong?
qsort(nums,length,sizeof(unsigned short) * sub_length,compare);
// ================
// "After" output
printf("After:\n");
for (index = 0; index < length; index++)
{
printf("[");
for (index2 = 0; index2 < sub_length - 1; index2++)
printf("%2hu,nums [index][sub_length - 1]);
}
/* ------------
* Cleanup
* ------------ */
for (index = 0; index < length; index++)
free(nums [index]);
free(nums);
return EXIT_SUCCESS;
}
解决方法
为了对行进行排序,您必须了解 qsort
的相邻元素将是 指向 unsigned short
的指针。由于 qsort
compare 需要一个 指向相邻元素的指针,它将是一个 指向指针的指针 unsigned short
。因此,您在比较中需要处理两级间接,例如
/* compare for adjacent ROW pointers - descending order */
int compare_desc (const void *a,const void *b)
{
unsigned short *pa = *(unsigned short * const *)a,*pb = *(unsigned short * const *)b;
return (*pa < *pb) - (*pa > *pb);
}
现在一个简短的例子是:
#include <stdio.h>
#include <stdlib.h>
#define ROWS 10
#define COLS ROWS
/* compare for adjacent ROW pointers - descending order */
int compare_desc (const void *a,*pb = *(unsigned short * const *)b;
return (*pa < *pb) - (*pa > *pb);
}
int main (void) {
unsigned short **nums = NULL;
nums = malloc (ROWS * sizeof *nums);
if (!nums) {
perror ("malloc-nums");
exit (EXIT_FAILURE);
}
for (int i = 0; i < ROWS; i++) {
nums[i] = malloc (COLS * sizeof *nums[i]);
if (!nums[i]) {
perror ("malloc-nums[i]");
exit (EXIT_FAILURE);
}
for (int j = 0; j < COLS; j++) {
nums[i][j] = i * COLS + j;
printf (j ? " %3hu" : "%3hu",nums[i][j]);
}
putchar ('\n');
}
qsort (nums,ROWS,sizeof *nums,compare_desc);
puts ("\nrows sorted descending,columns sorted ascending\n");
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++)
printf (j ? " %3hu" : "%3hu",nums[i][j]);
putchar ('\n');
free (nums[i]);
}
free (nums);
}
示例使用/输出
$ ./bin/qsort_ptr2ptr
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69
70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98 99
rows sorted descending,columns sorted ascending
90 91 92 93 94 95 96 97 98 99
80 81 82 83 84 85 86 87 88 89
70 71 72 73 74 75 76 77 78 79
60 61 62 63 64 65 66 67 68 69
50 51 52 53 54 55 56 57 58 59
40 41 42 43 44 45 46 47 48 49
30 31 32 33 34 35 36 37 38 39
20 21 22 23 24 25 26 27 28 29
10 11 12 13 14 15 16 17 18 19
0 1 2 3 4 5 6 7 8 9
如果这就是您想要的,如果您还有其他问题,请告诉我。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。