qsort ()의 비교 함수에서 구조체의 값 사용-C99-불완전한 유형에 대한 포인터 역 참조

초과

나는 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] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

C의 불완전한 유형 큐에 대한 역 참조 포인터

분류에서Dev

불완전한 유형 구조체에 대한 C 역 참조 포인터

분류에서Dev

불완전한 유형 C에 대한 역 참조 포인터

분류에서Dev

헤더의 typedef 구조체 및 불완전한 유형에 대한 역 참조 포인터

분류에서Dev

C : 불완전한 유형의 단일 연결 목록에 대한 역 참조 포인터

분류에서Dev

불완전한 유형에 대한 역 참조 포인터

분류에서Dev

불완전한 유형에 대한 역 참조 포인터

분류에서Dev

오류 : 불완전한 유형에 대한 포인터 역 참조-C 언어

분류에서Dev

구조체를 사용하여 불완전한 형식에 대한 포인터 역 참조

분류에서Dev

구조 및 포인터 오류 : 불완전한 유형에 대한 포인터 역 참조

분류에서Dev

C 오류 : 불완전한 유형 연결 목록에 대한 포인터 역 참조

분류에서Dev

C99의 구조체 내에서 열거 형 값의 너비 적용

분류에서Dev

C ++ 포인터에서 배열의 대상 구조체를 포함하여 구조체에 대한 값 읽기

분류에서Dev

구조의 두 필드를 사용하여 qsort에 대한 함수를 비교합니까?

분류에서Dev

float C 배열에 대한 공용체 유형 (구조체도 포함)의 포인터

분류에서Dev

int 및 struct 유형의 포인터를 사용하는 함수에서 포인터가 반환 한 주소를 어떻게 역 참조합니까?

분류에서Dev

구조체 변수에 대한 포인터 역 참조

분류에서Dev

구조체의 값에 접근하기위한 Rust와 C / C ++ 포인터 비교

분류에서Dev

char 포인터 C ++에 대한 포인터 역 참조

분류에서Dev

C ++에서 함수의 반환 유형으로 포인터 또는 참조를 사용하는 것에 대한 경험 규칙이 있습니까?

분류에서Dev

객체에 대한 포인터의 std :: vector의 각 요소를 역 참조

분류에서Dev

MxArray에 대한 포인터 역 참조

분류에서Dev

C의 구조체 유형에 대한 포인터 캐스팅 이해

분류에서Dev

함수에 전달 된 구조체의 배열에 대한 C 포인터

분류에서Dev

C ++ / CLI의 기본 유형에 대한 void * 역 참조

분류에서Dev

C에서 0에 대한 포인터 역 참조

분류에서Dev

C의 사용자 입력에 대한 구조 요소 확인 및 비교

분류에서Dev

사전 증가 연산자를 사용한 포인터 역 참조에 대한 포인터

분류에서Dev

포인터 뒤의 값에 대한 참조

Related 관련 기사

  1. 1

    C의 불완전한 유형 큐에 대한 역 참조 포인터

  2. 2

    불완전한 유형 구조체에 대한 C 역 참조 포인터

  3. 3

    불완전한 유형 C에 대한 역 참조 포인터

  4. 4

    헤더의 typedef 구조체 및 불완전한 유형에 대한 역 참조 포인터

  5. 5

    C : 불완전한 유형의 단일 연결 목록에 대한 역 참조 포인터

  6. 6

    불완전한 유형에 대한 역 참조 포인터

  7. 7

    불완전한 유형에 대한 역 참조 포인터

  8. 8

    오류 : 불완전한 유형에 대한 포인터 역 참조-C 언어

  9. 9

    구조체를 사용하여 불완전한 형식에 대한 포인터 역 참조

  10. 10

    구조 및 포인터 오류 : 불완전한 유형에 대한 포인터 역 참조

  11. 11

    C 오류 : 불완전한 유형 연결 목록에 대한 포인터 역 참조

  12. 12

    C99의 구조체 내에서 열거 형 값의 너비 적용

  13. 13

    C ++ 포인터에서 배열의 대상 구조체를 포함하여 구조체에 대한 값 읽기

  14. 14

    구조의 두 필드를 사용하여 qsort에 대한 함수를 비교합니까?

  15. 15

    float C 배열에 대한 공용체 유형 (구조체도 포함)의 포인터

  16. 16

    int 및 struct 유형의 포인터를 사용하는 함수에서 포인터가 반환 한 주소를 어떻게 역 참조합니까?

  17. 17

    구조체 변수에 대한 포인터 역 참조

  18. 18

    구조체의 값에 접근하기위한 Rust와 C / C ++ 포인터 비교

  19. 19

    char 포인터 C ++에 대한 포인터 역 참조

  20. 20

    C ++에서 함수의 반환 유형으로 포인터 또는 참조를 사용하는 것에 대한 경험 규칙이 있습니까?

  21. 21

    객체에 대한 포인터의 std :: vector의 각 요소를 역 참조

  22. 22

    MxArray에 대한 포인터 역 참조

  23. 23

    C의 구조체 유형에 대한 포인터 캐스팅 이해

  24. 24

    함수에 전달 된 구조체의 배열에 대한 C 포인터

  25. 25

    C ++ / CLI의 기본 유형에 대한 void * 역 참조

  26. 26

    C에서 0에 대한 포인터 역 참조

  27. 27

    C의 사용자 입력에 대한 구조 요소 확인 및 비교

  28. 28

    사전 증가 연산자를 사용한 포인터 역 참조에 대한 포인터

  29. 29

    포인터 뒤의 값에 대한 참조

뜨겁다태그

보관