2014-04-26 3 views
1

나는 온라인에서 찾고 있지만 지금까지 아무 것도 내 문제를 이해하는데 도움이되지 못했다. 현재 각 단어 목록을 포함하는 두 개의 목록을 만들려고합니다. 각 공백은 단어 구조체를 포함하며 각 단어 구조체는 30 개의 doc_list 구조체 목록입니다. 메모리를 할당하고 단어 목록 구조체 내에 char *를 저장할 수 있었지만 메모리를 할당하고 doc_list 구조체 내에 char *을 저장하려고하면 세그먼트 화 오류가 발생합니다. 내 doc_list 구조체를 내 word_list 구조체와 똑같은 방식으로 선언했기 때문에 혼란 스럽습니다. 다음은 구조체 내의 char * 값을 C로 구조체 내에 초기화하기

내가 어디서 나는 문서 이름 char * 값을 저장 내 삽입 기능에서 다음
#define BUFFSIZE 1000 
#define STOPLIST_INDEX 0 
#define DOCUMENTS_INDEX 1 

struct HashTable{ 
    int tableSize; 
    struct word_list** wordList; 
}; 

struct word_list{ 
    char* word; 
    struct doc_list** docList; 
}; 

struct doc_list{ 
    char* docName; 
    int timesAppear; 
}; 
//Initialing lists associated with hash table 
struct HashTable** initialize_hash_table(int argc, char** argv) 
{ 
    int k; //HashTables 
    int i; //Words 
    int q; //Document names 
    struct HashTable** hashTable = calloc(2, sizeof(struct HashTable **)); 
    for(k =0; k < 2; k++) 
    { 
    hashTable[k] = calloc (1, sizeof(struct HashTable *)); 
    hashTable[k]->wordList = calloc(BUFFSIZE, sizeof(struct word_list **)); 

    for(i = 0; i < BUFFSIZE; i++) 
    { 
     hashTable[k]->wordList[i] = calloc(1, sizeof(struct word_list *)); 
     hashTable[k]->wordList[i]->docList = calloc(30, sizeof(struct doc_list**)); 
     for(q = 0; q < 30; q++) 
     { 
      hashTable[k]->wordList[i]->docList[q] = calloc(1, sizeof(struct doc_list*)); 
     } 
    } 
    } 


    return hashTable; 
} 

이 내 해시 테이블을 초기화 내 C 파일에서 내 구조체

를 초기화입니다 세분화 오류. 나는 내 doc_list 구조체를 내 word_list 구조체를 초기화 한 것과 똑같은 방식으로 초기화했기 때문에 왜 이런 일이 발생하는지 이해할 수 없다. 나는 무슨 일이 일어나고 무엇을 믿는

int insert(struct HashTable** hashTable, char* document_word, char* filename, int index) 
{ 
    //create the hash key 
    int key = hashFunction(document_word, BUFFSIZE); 
    //Check if word exists in Stop List 
    if(index == 0 || hashTable[STOPLIST_INDEX]->wordList[key]->word == NULL) 
    { 
     //insert into list 
     hashTable[index]->wordList[key] = malloc(sizeof(struct word_list*)); 
     hashTable[index]->wordList[key]->word = strdup(document_word); 
     printf("%s%s\n", "INSERTED VALUE: ", hashTable[index]->wordList[key]->word); 
     //Add filename to words' document list 

     int w = 0; 
     puts("segfaulting here"); 
     puts("1"); 
     hashTable[index]->wordList[key]->docList[w] = malloc(sizeof(struct doc_list*)); 
     hashTable[index]->wordList[key]->docList[w]->docName = strdup(filename); 
     printf("%s%s\n", "INSERTED ", filename); 
     printf("\n"); 
    } 
    return 0; 
} 

은 단어에 대한 메모리를 할당하지 않지만 doc_list 구조체의 어느 것도 어떤 이유로 NULL 선언되지중인 경우 모든 단어 구조체는 NULL 선언되고 있다는 점이다. word_list 구조체와 똑같은 방식으로 메모리를 할당했습니다.

출력 내가 프로그램을 실행 이것이다 : 내가 잘못 뭐하는 거지

Hashing filename:stopwords.txt 
--------- 
INSERTED VALUE: a 
segfaulting here 
1 
Segmentation fault (core dumped) 

?

+0

당신은 당신의 코드를 상당히 단순화 할 수 있습니다 레벨 포인터 두 개 대신에 레벨 포인터. 예를 들어,'struct HashTable {int tableSize; 구조체 word_list * wordList; };'. –

답변

0

문제는 내가 참조 :

hashTable[k] = calloc (1, sizeof(struct HashTable *)); 

hasTable[k]struct HashTable* 인의

hashTable[k] = calloc (1, sizeof(struct HashTable)); 

유형을 변경해야합니다. 가리키는 개체의 크기는 struct HashTable이어야하며 struct HashTable*이 아니어야합니다.

에서 비슷한 오류가 있습니다 : 그것은 할 필요가

struct HashTable** hashTable = calloc(2, sizeof(struct HashTable **)); 

:

struct HashTable** hashTable = calloc(2, sizeof(struct HashTable*)); 

쉽게 sizeof(struct HashTable*) 때문에 오류를 볼 수 없습니다 대부분의 경우 sizeof(struct HashTable**) 같다가.

이러한 오류의 더 많은 부분은 initialize_hash_table입니다.

hashTable[k]->wordList[i]->docList = calloc(30, sizeof(struct doc_list**)); 

hashTable[k]->wordList[i]->docList[q] = calloc(1, sizeof(struct doc_list)); 

당신은 insert 유사한 오류가있는 것으로

hashTable[k]->wordList[i]->docList = calloc(30, sizeof(struct doc_list*)); 

hashTable[k]->wordList[i]->docList[q] = calloc(1, sizeof(struct doc_list*)); 

요구해야합니다.당신이 실제로 메모리가 제로 필요한 경우에만 calloc를 사용

hashTable[index]->wordList[key] = malloc(sizeof(struct word_list*)); 

hashTable[index]->wordList[key]->docList[w] = malloc(sizeof(struct doc_list)); 
0

팁으로

hashTable[index]->wordList[key] = malloc(sizeof(struct word_list)); 

hashTable[index]->wordList[key]->docList[w] = malloc(sizeof(struct doc_list*)); 

요구해야합니다. malloc이 빠릅니다.
또한 진리 값을 0으로 표준화해야하는 경우가 아니면 0NULL\0까지 부등식을 테스트 할 필요가 없습니다. 1이고, 심지어 !!이 바람직하다. !은 0으로 동등 함을 나타냅니다.

하지만 당신의 진짜 문제는 뭔가 다른 : 2 struct HashTable**에 대한

struct HashTable** hashTable = calloc(2, sizeof(struct HashTable **)); 

위의 라인은 메모리 제로 alloates, 저장도 sttruct HashTable**을 입력있다 hashTable의 포인터!
실제로는 2 struct HashTable*의 공간을 할당하려고합니다. 당신을 죽이지 않는이 하나의 특정 경우

, 두 포인터 타입이 아키텍처에 동일한 양의 공간을 사용하는 일, 그러나 더 나쁜 결과를 나중에 반복되는 패턴, 그리고 너무 적은 메모리 리드를 할당하기 때문에 으로 정의 된 동작 오버런을 버퍼 오버런하려면 아무 일도 일어나지 않을 수도 있습니다. 당신이 메모리 블록에 대한 포인터 p를 가리 키도록하려는 경우

, 따라서 할당 : 멀리 오해 너무 쉽기 때문에

p = malloc(count * sizeof *p); 
p = calloc(count, sizeof *p); /* only for zeroed memory */ 

당신은, 유형에 sizeof을 사용하지 않으려는, 하나 이상의 간접 레벨을 추가하거나 생략하거나 완전히 관련없는 유형을 취하는 것.
VLA 이름을 sizeof으로 지정하지 않으면 이 아니며은 인수를 평가하지만 형식을 가져오고 컴파일 - ime-constant를 유도합니다.

몇 가지 더

당신은 읽어야 하나를 사용하는 당신이 당신의`struct` 정의를 변경하는 경우