나는 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;
}
메인에서 배열을 인쇄하면 word : occurences의 올바른 정렬되지 않은 값이 제공됩니다.
편집하다:
시간을내어 도움을 주신 모든 분들 덕분에 이제 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()
또는 다른 것을 사용하는 배열을 할당해야한다고 생각합니다 . 하지만 제가 정말로해야한다고 생각하는 것은 한 걸음 물러서서 데이터 구조의 도면을 만들고 그 안에 포함 된 다양한 개체의 수명과 그 수명을 추적하여 누출이 없도록 관리하는 방법에 대해 생각하는 것입니다. double frees 또는 더 이상 유효하지 않은 객체에 대한 포인터 역 참조.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다