我对 C 相当陌生,正在努力正确使用 C stdlib qsort() 函数。
这与教育相关,因此,如果这很重要,我只能使用 C99 和标准库。
我有一个从 HashTable 中取出的项目列表,并将其放入 HashItem **array 中,但是当对其进行排序时,我正在使用比较函数,我无法从结构中获取正确的值。我环顾四周并看到了一些解决方案,但它们似乎都导致了
[Error] dereferencing pointer to incomplete type
这是结构:
typedef struct {
char *word;
int occurences;
} HashItem;
我有兴趣按出现值进行比较和排序。
这是调用 qsort 的代码:
int n = array->number_of_values;
HashItem **standard_array = array_getarray(array);
qsort(standard_array, n, sizeof(HashItem*), compare_func);
这是比较函数:
int compare_func(const void *a, const void *b){
const struct HashItem* aa = (HashItem*)a;
const struct HashItem* bb = (HashItem*)b;
int val_1 = aa->occurencies;
int val_2 = bb->occurencies;
if(val_1 == val_2){
return 0;
}else if(val_1 > val_2){
return 1;
}else{
return -1;
}
}
抱歉,格式不对,我是新手,才在这里提问。
希望您能帮忙,谢谢。
数组代码:
/*DynArray is a dynamically resizing array that is used to hold values and retain size data throughout*/
typedef struct{
int number_of_values;
int capacity;
HashItem **items;
}DynArray;
/*Method to create a new dynamic array and return it */
DynArray* array_new(int file_size){
DynArray *array = malloc(sizeof(DynArray));
array->number_of_values = 0;
array->capacity = file_size / 10;
printf("capacity is %d " , array->capacity);
array->items = malloc(sizeof(HashItem*)* array->capacity);
}
/*Method used to increase the size of the array and reallocate memory*/
void array_increase_if_full(DynArray *array){
if (array->number_of_values >= array->capacity){
array->capacity *= 1.25;
array->items = realloc(array->items, sizeof(HashItem)*array->capacity);
}
}
/*Method to add a string to the dynamic array specified */
void array_append(DynArray *array, HashItem *item){
array_increase_if_full(array);
array->items[array->number_of_values] = item;
//printf("item %s added \n at position %d ", array->items[array->number_of_values]->word, array->number_of_values);
array->number_of_values++;
}
/*Method used to get value at specified position for given array*/
HashItem *array_get(DynArray *array, int position){
if(position >= array->number_of_values || position <0){
printf("Index specified out of range");
exit(1);
}
//printf("item %s at position %d retrieved", array->items[position]->word, position);
return array->items[position];
}
HashItem **array_getarray(DynArray *array){
HashItem **toreturn[array->number_of_values];
int i;
for(i = 0; i < array->number_of_values; i++){
toreturn[i] = array_get(array, i);
}
return toreturn;
}
从 main 中打印数组给出了正确的未排序的 word:occurrences 值
编辑:
感谢大家花时间提供帮助,现在在 Michaels 的建议下处于工作状态,我不再使用 array_getarray() 方法,而是使用:
int n = array->number_of_values;
int i;
HashItem **standard_array = malloc(n*sizeof(HashItem*));
for(i = 0; i < n; i++){
standard_array[i] = array_get(array, i);
printf("%s : %d \n" , standard_array[i]->word, standard_array[i]->occurences);
}
最佳答案
您构建声明:
typedef struct {
char *word;
int occurences;
} HashItem;
声明匿名结构的 typedef 名称。有一个 HashItem
类型是一个结构体,但没有 struct HashItem
类型。
因此,当您的 compare_func()
具有以下声明时:
const struct HashItem* aa = (HashItem*)a;
const struct HashItem* bb = (HashItem*)b;
这些struct HashItem*
变量是指向前向声明的struct HashItem
的指针,与上面的HashItem结构无关。
只需将这些变量声明更改为:
const HashItem* aa = (HashItem*)a;
const HashItem* bb = (HashItem*)b;
和/或将结构声明更改为:
typedef struct HashItem {
char *word;
int occurences;
} HashItem;
但是,还有另一个问题(如其他答案中提到的):您显然正在对指向 HashItem
对象的指针数组进行排序,但您的 compare_function()
正在被写入就像您正在对对象数组(而不是指针)进行排序一样。
解决这个问题:
int compare_func(const void *a, const void *b)
{
// get HashItem*'s from the HashItem**'s
const HashItem* aa = *((HashItem**)a);
const HashItem* bb = *((HashItem**)b);
int val_1 = aa->occurencies;
int val_2 = bb->occurencies;
if (val_1 == val_2) {
return 0;
} else if (val_1 > val_2) {
return 1;
} else {
return -1;
}
}
最后(无论如何现在),该函数将地址返回到本地数组,因此它指向的数据不再有效:
HashItem **array_getarray(DynArray *array){
HashItem **toreturn[array->number_of_values];
int i;
for(i = 0; i < array->number_of_values; i++){
toreturn[i] = array_get(array, i);
}
return toreturn;
}
我认为您需要使用 malloc()
或 calloc()
或其他方法来分配要重新调整的数组。但我真正认为你需要做的是退后一步,创建一些数据结构的绘图,并考虑其中包含的各种对象的生命周期,以及如何跟踪和管理这些生命周期,这样就不会出现泄漏,双重释放,或指针取消引用不再有效的对象。
关于c - 在 qsort() 的比较函数中使用结构体中的值 - C99 - 取消引用指向不完整类型的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22854025/