2017-11-30 25 views
0

내부에 존재하는 나는 그런C - 포인터 구조체의 배열을 확장 이미

typedef struct bucket{ 
    char * value; 
    char * key; 
}BUCKET; 

typedef struct item{ 
    struct bucket * data; 
    struct item * next; 
    struct item * prev; 
}ITEM; 

typedef struct base{ 
    struct item * first; 
}BASE; 

typedef BASE *SPACE; 

그것은 내가 그것으로해야 할 일을했을 모든 것을 완벽하게 작동로 선언 된 구조체의 배열을 가지고있다. 기본적으로 나는 C에서 hashmap의 구현을해야만한다. 나는 그것을 할 수 있었지만이 작업을 완전히 고수했다. 해시 맵을 사용자가 크기를 재조정 할 수 있도록해야합니다.

SPACE *hashmap = malloc(sizeof(SPACE *) * 5); 

을하며 프로그램의 목적을 위해 완벽하게 작동합니다 :

내가 크기 5의 해시 맵을 원하는 경우에, 나는 그렇게. 나는 다음과 같은 코드 블록을 사용하여 크기를 조정하려고하면

그러나 :

void expandHashspace(SPACE *hashmap){ 
    printf("Please enter how large you want the hashspace to be.\n"); 
    printf("Enter a number between %d and 100. Enter any other number to exit.\n>",hashSpaceSize); 
    int temp = 0; 
    scanf("%d",&temp); 
    if(temp>100 || temp<hashSpaceSize){ 
     printf("Exiting...\n"); 
    } 
    else { 
     SPACE *nw = NULL; 
     nw = realloc(hashmap, sizeof(SPACE *) * temp); 
     hashmap = nw; 
     hashSpaceSize = temp; 
     printf("Your hashspace is now %d rows long.\n", hashSpaceSize); 
    } 
} 

을 또한 제대로 작동합니다. 그러나 해시 맵 자체를 활용하려고하면 세그먼트 화 오류가 발생합니다. 또는 SIGSEGV 신호 11.

예를 들어, 다음과 같은 표시 기능이 있습니다.

void displayHashspace(SPACE *hashmap){ 
    printf("\n"); 
    int j = 0; 
    for(int i = 0; i < hashSpaceSize && hashmap; i++){ 
     BASE *linkedList = hashmap[i]; 
     if(linkedList) { 
      ITEM *node = linkedList->first; 
      printf("\n[HASH %d]\n", i); 
      while (node) { 
       printf("\t[BUCKET %d]\n\t[VALUE] : %s\n\t[KEY] : %s\n\n",j, node->data->value, node->data->key); 
       node = node->next; 
       j++; 
etc... 

는 CLion의 디버깅을 사용하여, 나는이 실현 : 의이 해시 맵의 크기는 [0-2]를 해시 맵 존재한다는 것을 의미 할 것입니다 3입니다 가정 해 봅시다. 해시 맵의 크기를 10으로 조정하면 크기를 조정할 수 있습니다. 그러나 표시하는 동안 hashmap [3]의 주소는 정말 이상합니다. 다른 모든 주소는 거의 8 자리 이상인 꽤 길지만, hashmap [3]의 주소는 항상 0x21입니다.

그런 다음 linkedList가 hashmap [3] 인 ITEM *node = linkedList->first;에 도달하면 조각화 오류가 발생합니다.

다른 예가 있습니다. 여기 내 저축 기능이 있습니다 :

void saveHash(SPACE *hashmap){ 
    FILE *f = fopen("hashmap.hsh","w"); 
    fprintf(f,"%d\n",hashSpaceSize); 
    for(int i = 0; i < hashSpaceSize;i++){ 
     if(hashmap[i]){ 
      ITEM *save = hashmap[i]->first; 
      do{ 
       fprintf(f,"---\n%s\n%s\n",save->data->value,save->data->key); 
       save = save->next; 
      }while(save); 
etc... 

여기 이야기가 다릅니다. 크기 조정 후 충돌하기 전에 hashmap [0]에 도달 할 수 있습니다. 디버거를 사용하여 어떻게 든 hashmap [0] -> (확장 전에 일반적으로 작동하는) 저장에 저장된 값이 VALUE 변수가 갑자기 NULL로 설정되어 버려서 충돌이 발생하는 것으로 나타났습니다.

확장 후에 모든 "새"BASE를 NULL로 설정하려고했지만 expandHashspace()을 사용한 후 저장 기능이 여전히 중단되었습니다.

내가 뭘 잘못하고 있니?

+0

'SPACE * hashmap = malloc (sizeof (SPACE *) * 5);'는 유형 오류입니다. 왼쪽에는 타입 (SPACE * hashmap'), 오른쪽에는 sizeof (SPACE *) 타입이 있습니다. 왼쪽에는 하나의 별이 더 있어야합니다 ('int * p = malloc (sizeof (int))'처럼). – melpomene

+1

'hashmap'은'expandHashspace'의 지역 변수입니다. 함수에 반환 할 시간이 지나면 사라질 것이므로 할당하는 것은 무의미합니다. – melpomene

+0

젠장, 난 바보 야. 해시 맵 자체를 반환하는 메서드를 만들어 이제는 작동합니다. – txtman

답변

0

해시 맵이 해당 메소드의 로컬 변수이기 때문에 hashmap에 메모리를 재 할당 할 수 없습니다. 모든 것을 의미하는 것은 혼란스러운 악몽이되었습니다.

아무것도 반환하지 않고 해시 맵 자체를 반환하면 아무 문제도 해결되지 않습니다.