比较比特中的C比较分类分割错误

时间:2017-08-31 21:07:27

标签: c sorting segmentation-fault comparison

我最近才开始使用C编程,而且我遇到了比较排序算法的麻烦。我将发布下面的代码,但基本上我有三个单独的比较函数,帮助排序unsigned int的数组。

第一个比较函数按升序排序,第二个按降序排序,第三个比较函数是根据int的二进制表示中的1的数量进行排序 - 这三个中的最后一个给了我my分段故障。

思想?

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

/* ASIZE is the size of the array to sort (number of 32-bit integers) */
#define ASIZE 100
/* NFCNS is the number of different sort functions defined in the comp array */
#define NFCNS 3

/* defines the type compare_fcn to be a pointer to a function that takes two
 * constant void pointers and returns an integer. */
typedef int (*compare_fcn)(const void *, const void *);

/* randomly permute the elements in an array of size 32-bit integers.
 * Permutation is done in place. */
void shuffle(uint32_t *a, int size) {
    int i = 0;  /* Scratch */

    /* Seed the random number generator with the current time.  Since time(2)
     * returns a time_t, the code casts it properly. */
    srandom((unsigned int) time(NULL));

    /* Permute the elements */
    for (i = 0; i<size; i++) {
    int j = random() % size;
    int k = random() % size;
    int tmp = 0;

    if (j == k) continue;
    tmp = a[j];
    a[j] = a[k];
    a[k] = tmp;
    }
}

/* Print the 32-bit array (of size integers) to stdout.  Print the integers as
 * 3-digit, zero-padded integers, 10 integers to a line. */
void dump_array(uint32_t *a, int size) {
    int i = 0;  /* Scratch */

    for ( i = 0; i < size; i++) {
    if ( i % 10 == 0) printf("\n");
    printf("%03d ", a[i]);
    }
    if ((size -1) % 10 != 0 ) printf("\n");
}

/* 
 * qsort comparison functions compare the data pointed to by two pointers.  In
 * this program, the data is always interpreted as 32-bit, unsgned integers
 * (uint32_t's).  Comparison functions need to cast the pointers into the right
 * type and carry out the comparison.  The return value is <0 if the first data
 * should appear before the second, >0 if the first should appear after the
 * second, and 0 if there is no preference.
 */

/*
 * Compare the elements pointed to b a and b to each other as 32-bit integers.
 */
int compare_ab(const void *a, const void *b) {
    const uint32_t *aa = (const uint32_t *) a;
    const uint32_t *bb = (const uint32_t *) b;
    return *aa - *bb;
}


int reverse_compare_ab(const void*a, const void *b){
    const uint32_t *aa = (const uint32_t *) a;
    const uint32_t *bb = (const uint32_t *) b;
    return *bb - *aa;
}

int compare_by_ones(const void*a, const void*b){
    const uint32_t *aa = (const uint32_t *) a;
    const uint32_t *bb = (const uint32_t *) b;

    int count1 = 0;
    int count2 = 0;

    for(int i = 0; i < 32; i++)
    {
        uint32_t temp1 = (uint32_t) *aa >> i;
        uint32_t one = 0x01;
        temp1 = temp1 & one;
        if(temp1 == one) count1++;

        uint32_t temp2 = (uint32_t) *bb >> i;
        temp2 = temp2 & one;
        if(temp2 == one) count2++;
    }

    return -(count2 > count1);
}

/* Definition of the array to sort */
uint32_t a[ASIZE];

/* Definition of the array of comparison functions */
compare_fcn comp[NFCNS];

/*
 * Main driver program.  Initialize an array with the integers from 0-ASIZE,
 * permute it, and sort it with different comparisons.  Print the initial
 * array, the permuted array, and each sort to stdout.
 */
int main(int argc, char **argv) {
    int i = 0;      /* Scratch */

    /* Initialize array and functions */
    for ( i = 0 ; i < ASIZE; i++)
    a[i] = i;

    /* Initialize function table */
    comp[0] = compare_ab;

    comp[1] = reverse_compare_ab;

    dump_array(a, ASIZE);

    /* Permute */
    shuffle(a, ASIZE);
    dump_array(a, ASIZE);

    /* Sorts */
    for (i=0; i < NFCNS; i++) {
    qsort(a, ASIZE, sizeof(uint32_t), comp[i]);
    dump_array(a, ASIZE);
    }
}    

1 个答案:

答案 0 :(得分:0)

正如其他评论者所说,您的代码至少有2个错误。

更明显的错误是你没有初始化comp数组的所有成员,所以这个循环:

for (i=0; i < NFCNS; i++) {
  qsort(a, ASIZE, sizeof(uint32_t), comp[i]);
  dump_array(a, ASIZE);
}

在其上一次迭代访问comp[2],仍为NULL。通过NULL指针调用函数是分段错误的直接原因。

不太明显的错误是,您的compare_by_ones qsort比较器返回0-1,但从不1,因此生成的排序顺序不会正确(甚至可预测)。