条件跳转或移动取决于未初始化的值?

时间:2011-05-03 23:38:26

标签: c memory-management malloc 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;
}

1 个答案:

答案 0 :(得分:6)

您的createEntry函数未初始化next字段。使用单元化的东西的实际点在你所显示的代码之外(在search.c的第214行),但是根据你所显示的,我的猜测是next字段。

其他一些挑剔:

  • 将指针隐藏在typedef中常常令人困惑。它让人不清楚 读者是否忘记使用指针。有时它还不清楚 作家,也会导致一个错误。因此,我建议您更改Entry typedef 是这样的:typedef struct Entry_ Entry;
  • 结构名称末尾的下划线是不必要的,看起来像一个错字。 因此,仅使用struct Entry称呼它会更好。
  • 在C中,不需要对malloc的结果进行类型转换,这样做可以隐藏a 缺少#include <stdlib.h>
  • sizeof(char)按照定义1在C中,所以我会将其留在malloc中 调用

除了那些东西,这个功能对我来说很好看。感谢检查和报告错误。