c - C 中的 QSORT 函数

标签 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;
}

最佳答案

compare_names() 中,您在强制转换后不适本地取消引用参数。局部变量的类型是 char ** 类型,但您将参数转换为 char ** 并取消引用,结果是 char *.

nameanameb 是指向 main() 中声明的数组 names[] 元素的指针.也就是说,它们的类型实际上是指向 char * 的指针。当您取消引用这些参数但将它们分配给 char ** 时,您会导致局部变量将 char * 视为 char ** (您的编译器应该已针对此问题向您发出诊断警告)。现在,您采用 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);
}

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

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

关于c - C 中的 QSORT 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18242187/

相关文章:

c++ - 如何从文件中读取前 256 位并将它们存储在两个数组中

c - 在线程之间共享相同的 epoll 文件描述符可以吗?

C++ 通过指针实例化

c - 在 C 中使用 qsort() 并跳过特定的字符集

c - C语言中 float 相减

c++ - 如何获取 llvm 内联 asm 操作数类型?

c - 查找满足 i < j 且 A[i]**A[j] > A[j]**A[i] 的对 (A[i], A[j]) 的数量

Delphi 内存泄漏,指向 TStringList 的指针

C编程: void * argument is it really pointer to anything,我可以在那里传递函数指针吗

c - qsort结构数组删除一切