在C中的结构中初始化struct中的char *值

时间:2014-04-26 02:57:06

标签: c pointers struct

我一直在网上看,但到目前为止没有什么能帮助我理解我的问题。目前我正在尝试制作两个列表,每个列表都包含一个单词列表。每个空格都包含一个单词struct,每个单词struct中包含30个doc_list结构的列表。我已经能够在单词列表结构中分配内存和存储char *但是当我尝试分配内存并在doc_list结构中存储char *时,我得到了分段错误。我很困惑,因为我声明我的doc_list结构与我的word_list结构一样。

以下是我的结构的初始化

在我的C文件中,我初始化我的哈希表

#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;
} 

然后在我的插入函数中,我存储文档名称char *值是我得到分段错误的地方。我不明白为什么会发生这种情况,因为我初始化我的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)

我做错了什么?

2 个答案:

答案 0 :(得分:0)

我看到的问题:

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

需要更改为

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

hasTable[k]的类型为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 =  calloc(30, sizeof(struct doc_list*));

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

需要

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

insert中有类似的错误。

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

需要

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

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

需要

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

答案 1 :(得分:0)

提示:如果您确实需要将内存置零,请仅使用callocmalloc更快 此外,没有必要对0 NULL \0进行不平等测试,除非您需要将您的真值标准化为0 | 1,即便如此{ {1}}是首选。 !!在其任何伪装中等于0。

但你真正的问题是别的:

!

以上行为2 struct HashTable** hashTable = calloc(2, sizeof(struct HashTable **)); 分配了零内存,并将指针存储在struct HashTable**中,类型hashTable也是如此!
实际上你想为2 sttruct HashTable**分配空间。

在这个特定的情况下,它不会杀死你,因为这两种指针类型碰巧在这个体系结构上使用相同数量的空间,但它是一种模式,后来会重复使用更糟糕的结果,并且分配太少的内存会导致缓冲区溢出,因为未定义的行为意味着任何事情都可能发生(当然大多数都是坏事)。

如果要将指针p指向内存块,请按以下方式进行分配:

struct HashTable*

您不希望在类型上使用p = malloc(count * sizeof *p); p = calloc(count, sizeof *p); /* only for zeroed memory */ ,因为它太容易出错,添加或取消一个或多个间接级别或采用完全不相关的类型。
除非你将VLA命名为sizeof,否则它将评估其参数,但只获取类型并派生一个compile-ime常量。

您应该阅读更多内容: