我的qsort在Linux中出了什么问题?

时间:2016-09-05 04:02:49

标签: c linux qsort

我正在使用Mac OS来实现命令排序功能的一部分: 我的部分代码如下:

int compare(const void *p, const void *q) {
    return strcmp(*(char **)p, *(char **)q);
}
void sort_file(char *filename, int unique, int reverse) {
    /* TODO: Complete this function */
    /* Note: you will probably need to implement some other functions */
    char buf[1024][1024];
    int i=0;
    FILE * fp;
    if(!(fp=fopen(filename,"r"))){
        perror("Open error!");
        exit(0);
    }
    while(fgets(buf[i],1024,fp)){
        printf("%s",buf[i]);
        i++;
    }
    qsort(buf, i, sizeof(char *), compare);
}

结果始终显示segmentation fault: 11 任何人都可以告诉我这是什么问题以及如何修改它?

我仍然想知道,如果我不知道一行和文件中代码的最大大小,如何定义我的数组?

我从这个页面得到了这个想法: http://www.anyexample.com/programming/c/qsort__sorting_array_of_strings__integers_and_structs.xml

2 个答案:

答案 0 :(得分:5)

你没有指针数组;你有一个数组数组。数组数组中的每个元素都有一个特定的固定步长为1024 charqsort需要知道这一点,而你却没有说出来。首先改变这个:

qsort(buf, i, sizeof(char *), compare);

到此:

qsort(buf, i, sizeof *buf, compare);

现在qsort知道char数组数组中每个“东西”的大小。

接下来,应该更改比较器以考虑要传递的地址以及与数组数组相关的地址。传递给比较器的每个地址都是元素所在的位置。但是你的元素都是char[1024]。某些char[1024]的地址不是char**,而是char(*)[1024]。这里没有涉及指针的指针。你的比较器可以简单地是:

int compare(const void *p, const void *q) 
{
    const char (*lhs)[1024] = p;
    const char (*rhs)[1024] = q;
    return strcmp(*lhs, *rhs);
}

接下来,您的控制循环中没有限制器可以防止数组数组溢出。简而言之,这个:

while(fgets(buf[i],1024,fp))

应该是这样的:

while(i < 1024 && fgets(buf[i],1024,fp))

理想情况下,1024应该表示为某个常量,以避免幻数喷洒。

最后,你在函数中泄漏了一个开放的FILE*。不是一个好的计划。确保fclose()文件指针。

答案 1 :(得分:2)

我看到的问题:

错误的qsort

参数
qsort(buf, i, sizeof(char *), compare);

需要:

qsort(buf, i, sizeof(buf[0]), compare);

由于buf+1buf之间的差异为1000 char s,因此使用sizeof(char*)作为第三个参数是错误的。

compare

中的参数拼写错误

原始指针的类型为char (*)[1000],而不是char**。因此,您需要使用:

int compare(const void *p, const void *q) {

   char (*p1)[1000] = (char (*)[1000])(p);
   char (*q1)[1000] = (char (*)[1000])(q);

   return strcmp(*p1, *q1);
}