2011-05-03 33 views
2

我收到以下错误,当我的valgrind我的C程序:有条件的跳转或移动取决于未初始化的值?

Conditional jump or move depends on uninitialised value(s) 
==7092== at 0x40298E: main (search.c:214) 
==7092== Uninitialised value was created by a heap allocation 
==7092== at 0x4C274A8: malloc (vg_replace_malloc.c:236) 
==7092== by 0x40211B: createEntry (words.c:113) 
==7092== by 0x4027D9: parseIndex (search.c:170) 
==7092== by 0x402903: main (search.c:208) 

通常这会表明,我没有mallocing的结构大小合适,但我不认为是这样。这里有所有相关的代码,让我知道你的想法!

/* Entry_ 
* 
* @param filename filename and path 
* @param frequency how often the word appears 
* @param next  next entry in list 
*/ 

struct Entry_ { 
    char *filename; 
    int frequency; 
    struct Entry_* next; 
}; 

typedef struct Entry_* Entry; 

下面是创建输入功能的代码:

/* createEntry 
* 
* Creates a brand new entry object. 
* 
* @param filename  the filename where the entry occured 
* 
* @return success   new Entry 
* @return failure   NULL 
*/ 

Entry createEntry(char *filename) 
{ 
    Entry ent; 

    ent = (Entry) malloc(sizeof(struct Entry_)); /* This is line 113 in words.c */ 
    if(ent == NULL) 
    { 
     fprintf(stderr, "Error: Could not allocate memory for Entry.\n"); 
     return NULL; 
    } 

    ent->filename = (char*) malloc(sizeof(char) * (strlen(filename) + 1)); 
    if(ent->filename == NULL) 
    { 
     free(ent); 
     fprintf(stderr, "Error: Could not allocate memory for Entry.\n"); 
     return NULL; 
    } 

    strcpy(ent->filename, filename); 

    ent->frequency = 1; 

    return ent; 
} 

编辑:新增内SEARCH.C

/* parseIndex 
* 
* Function that takes in an inverted index and returns 
* a HashTable containing all the words and their entries. 
* Returns NULL on failure. 
* 
* @param filename  name of the inverted index 
* 
* @return success   new HashTable 
* @return failure   NULL 
*/ 

HashTable parseIndex(char* filename) 
{ 
    HashTable table; 
    TokenizerT tok; 
    char* str; 
    int res; 
    Entry ent; 

    if(filename == NULL) 
    { 
     fprintf(stderr, "Error: Cannot parse NULL file.\n"); 
     return NULL; 
    } 

    table = createHT(hash, compStrings, destroyString, destroyWord, printWordHT); 
    if(table == NULL) 
    { 
     fprintf(stderr, "Error: Could not allocate space for HashTable.\n"); 
     return NULL; 
    } 

    tok = TKCreate(FILE_CHARS, filename); 
    if(tok == NULL) 
    { 
     fprintf(stderr, "Error: Could not allocate space for Tokenizer.\n"); 
     return NULL; 
    } 

    str = TKGetNextToken(tok); 
    res = strcmp(str, "files"); 
    free(str); 

    if(res != 0) 
    { 
     fprintf(stderr, "Error: Malformed index file.\n"); 
     return NULL; 
    } 

    /* Parse the file list */ 
    while((str = TKGetNextToken(tok)) != 0 && strcmp(str, "/files") != 0) 
    { 
     free(str); 
     str = TKGetNextToken(tok); 

     if(str == 0 || strcmp(str, "/files") == 0) 
     { 
      fprintf(stderr, "Error: Malformed index file.\n"); 
      return NULL; 
     } 

     ent = createEntry(str); /* Line 170 */ 

     if(file_list == NULL) 
     { 
      file_list = ent; 
     } 
     else 
     { 
      ent->next = file_list; 
      file_list = ent; 
     } 

     free(str); 
    } 

    free(str); 

    TKDestroy(tok); 
    tok = NULL; 

    return table; 
} 

int main(int argc, char** argv) 
{ 
    HashTable table; 
    Entry curr, next; 
    int i; 

    /* Validate the inputs */ 
    if((argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h') || argc != 2) 
    { 
     fprintf(stderr, "Usage: %s <inverted-index filename>\n", argv[0]); 
     return 1; 
    } 

    file_list = NULL; 

    table = parseIndex(argv[1]); /* Line 208 */ 
    assert(table != NULL); 

    curr = file_list; 
    i = 0; 

    while(curr != NULL) 
    { 
     next = curr->next; 

     printf("[%i]: %s\n", i, curr->filename); 

     free(curr->filename); 
     free(curr); 

     curr = next; 
    } 

    destroyHT(table); 
    table = NULL; 

    return 1; 
} 
+0

请问您能显示'search.c:214'吗? – 2011-05-03 23:46:46

回答

6

代码你createEntry功能无法初始化next领域。单元化内容的实际点在你所显示的代码之外(在search.c的第214行),但从你所显示的内容来看,我的猜测是next字段。

其他一些吹毛求疵:

  • 人们常常混淆隐藏一个typedef里面的指针。这使得 读者不清楚是否忘记使用指针。有时也不清楚 作家,这会导致错误。因此,我建议您将Entry typedef 更改为如下所示:typedef struct Entry_ Entry;
  • 结构名称末尾的下划线是不必要的,看起来像一个错字。因此,将它称为struct Entry将是更好的风格。
  • 在C,没有必要强制转换的malloc的结果,这样可以隐藏 失踪#include <stdlib.h>
  • sizeof(char)是用C定义1,所以我会离开了这一点在malloc 电话。

除了这些东西,这个功能对我来说看起来不错。检查和报告错误的荣誉。

+0

就是这样。谢谢您的帮助。我一直盯着这段代码很久,我甚至忘记检查它。 – Swift 2011-05-03 23:52:33

+0

这总是一个有趣的错误追踪没有任何形式的帮助。 – 2011-05-03 23:52:43

相关问题