내부에 존재하는 나는 그런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()
을 사용한 후 저장 기능이 여전히 중단되었습니다.
내가 뭘 잘못하고 있니?
'SPACE * hashmap = malloc (sizeof (SPACE *) * 5);'는 유형 오류입니다. 왼쪽에는 타입 (SPACE * hashmap'), 오른쪽에는 sizeof (SPACE *) 타입이 있습니다. 왼쪽에는 하나의 별이 더 있어야합니다 ('int * p = malloc (sizeof (int))'처럼). – melpomene
'hashmap'은'expandHashspace'의 지역 변수입니다. 함수에 반환 할 시간이 지나면 사라질 것이므로 할당하는 것은 무의미합니다. – melpomene
젠장, 난 바보 야. 해시 맵 자체를 반환하는 메서드를 만들어 이제는 작동합니다. – txtman