C 卡住了!。。分段错误、qsort\r、数组和指针的组合

C 卡住了!。。分段错误、qsort\r、数组和指针的组合,c,arrays,pointers,memory-leaks,qsort,C,Arrays,Pointers,Memory Leaks,Qsort,我希望我能简明扼要地说明我下面要做的事情 对于软件问题来说,代码相当复杂,我不认为我可以让它变得更简单,同时让其他人直接测试它 所以我把相关的部分切下来放在这里 为什么我会出现这个错误,你能帮我修复它吗 感谢您的帮助 多谢各位 char words[100][WORD_LENGTH]; char temp[WORD_LENGTH]; // scan the next %s from stream and put it to temp while(fscanf(

我希望我能简明扼要地说明我下面要做的事情

对于软件问题来说,代码相当复杂,我不认为我可以让它变得更简单,同时让其他人直接测试它

所以我把相关的部分切下来放在这里

为什么我会出现这个错误,你能帮我修复它吗

感谢您的帮助

多谢各位

    char words[100][WORD_LENGTH];

    char temp[WORD_LENGTH];

    // scan the next %s from stream and put it to temp
    while(fscanf(file, "%s", temp) > 0){
        // printf("reducer reads: %s\n", temp);

        strcpy(words[arr_i], temp);
        printf("%d -- %s\n", arr_i, words[arr_i]);

        arr_i++;

    }
在第二行,我得到了分割错误。(可能与valgrind一起泄漏)

摘自《曼格索特》:


根据
man qsort

qsort_r()函数与qsort()相同,只是 比较函数compar接受第三个参数

比较函数包含两个参数。

更新:真正的崩溃原因如下。您将传递给类型为
char[WORD\u LENGTH]
的数组的比较函数元素,而不是
char*
man qsort
示例中的比较函数元素。因此,传递给比较函数的参数是p1=&words[\ux],它是指向要比较的字符串的指针。而在字符指针的情况下,它将是
(char**)
,只是指向
char
/string指针的指针。因此,行
strcmp(*(char*const*)p1,*(char*const*)p2中的强制转换
是不必要且有害的,因为在您的情况下,最左侧的解引用是问题的原因。移除它们,只留下strcmp(p1,p2)。

作为旁注,此问题再次强调字符串数组声明之间的区别,如
char*[]
char[][]
WORD\u LENGTH
的定义是什么?@StefanoSanfilippo#define WORD\u LENGTH 255是否验证了“words”数组中的有效(长度、空终止)字符串?@EugeneSh。字符串是有效的,在strcpy程序正确打印它们之前。您确定要填充数组的100个位置吗?因为您在qsort中使用了
sizeof(words)/sizeof(words[0])
,即,(255*100)/255。你应该用
arr\u i
以防万一。我不明白。。。我从man qsort手册中复制了这个功能。哦,谢谢。所以我应该改为
静态int-cmpstringp(const-void*p1,const-void*p2,void*p3)
而不使用p3。对吗?你为什么需要第三个论点?只要比较函数只需要访问两个元素进行比较,就可以使用
qsort
@user4220128
qsort
本身是线程安全的
qsort_r
用于在必要时传递额外数据。您的比较函数可以安全地与纯
qsort
一起使用,即使存在线程。@user4220128。。。如果您试图同时从两个线程对同一数组进行排序,我想
qsort
也不会是线程安全的,但是
qsort\r
也是如此。
    int thunk = WORD_LENGTH; 
    qsort_r(&words, sizeof(words)/sizeof(words[0]), sizeof(words[0]), cmpstringp, &thunk);
static int cmpstringp(const void *p1, const void *p2) {
   /* The actual arguments to this function are "pointers to
      pointers to char", but strcmp(3) arguments are "pointers
      to char", hence the following cast plus dereference */

   return strcmp(* (char * const *) p1, * (char * const *) p2);
}