C中的QSORT功能

Kri*_*hna 1 c pointers qsort

在下面的代码中,一旦我删除了比较字符串的注释部分,我就会遇到seg 11错误.我无法理解为什么!其余的代码工作正常.任何帮助表示赞赏!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int compare_scores_desc(const void* scorea, const void* scoreb){
int a = *(int*)scorea;
int b = *(int*)scoreb;
return a-b;
}

int compare_names(const void* namea, const void* nameb){
char** a = *(char**)namea;
char** b = *(char**)nameb;
return strcmp(*a,*b);
}

int main(int argc, char* argv[]){
int scores[7] = {456,234,65,563,67,19,100};
int i;
qsort(scores,7,sizeof(int),compare_scores_desc);
puts("\nThese are the scores in order : \n");
for(i=0;i<7;i++)
    printf("%i\n",scores[i]);
char *names[] = {"Krishna","Rama","Bhishma","Arjuna"};
/*qsort(names,4,sizeof(char*),compare_names);*/
puts("------------------");
puts("The names in order are : \n");
for(i=0;i<4;i++)
    printf("%s\n",names[i]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)

jxh*_*jxh 6

compare_names(),你在演员表后不恰当地解除引用参数.局部变量的类型是类型char **,但是您将参数转换为char **取消引用并导致a char *.

nameanameb指向在中names[]声明的数组元素main().这意味着,它们的类型实际上是指针char *.当您取消引用这些参数但将它们分配给a时char **,会导致局部变量将其char *视为a char **(您的编译器应该已经发出了关于此问题的诊断警告).现在,您获取一个指针值为a char *,并在将其传递给时取消引用它strcmp().这会导致程序sizeof(char *)将字符串的字节视为strcmp()函数的指针值.由于4或8(或其他sizeof(char *))由可打印字符组成的字节重新解释为指针值很少产生有效指针,因此当strcmp()尝试使用这些指针时,会发生分段错误.

一种可能的解决方法是在初始化局部变量时不要取消引用.但是,参数是const void *,所以如果你声明你的局部变量是一个指向const类型的指针,你可以完全避免强制转换:

int compare_names(const void* namea, const void* nameb){
char* const * a = namea;
char* const * b = nameb;
return strcmp(*a,*b);
}
Run Code Online (Sandbox Code Playgroud)

请注意,compare_scores_desc()如果a - b导致有符号整数溢出,则实现失败.例如,如果aINT_MAXb-1.您应该修复您的实现以适用于所有情况.

int compare_scores_desc(const void* scorea, const void* scoreb){
const int *a = scorea;
const int *b = scoreb;
return (*a > *b) - (*a < *b);
}
Run Code Online (Sandbox Code Playgroud)