【问题标题】:Conditional jump or move depends on uninitialised values?条件跳转或移动取决于未初始化的值?
【发布时间】:2011-08-18 03:07:48
【问题描述】:

我在对 C 程序进行 valgrind 时遇到以下错误:

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)

通常这表明我没有为结构分配正确的大小,但我认为情况并非如此。这是所有相关的代码,让我知道你的想法!

/* 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;
}

【问题讨论】:

  • 请给我search.c:214好吗?

标签: c memory-management malloc valgrind


【解决方案1】:

您的 createEntry 函数未初始化 next 字段。使用单元化的实际点在您显示的代码之外(在 search.c 的第 214 行),但从您显示的内容来看,我的猜测是 next 字段。

其他一些挑剔:

  • 将指针隐藏在 typedef 中通常会让人感到困惑。它使人们不清楚 读者无论您是否忘记使用指针。有时不清楚 writer 也一样,这将导致错误。因此我建议您更改Entry typedef 变成这样:typedef struct Entry_ Entry;
  • 结构名称末尾的下划线是不必要的,看起来像是错字。 因此,将其称为 struct Entry 会更好。
  • 在C语言中,不需要对malloc的结果进行类型转换,这样做可以隐藏一个 失踪#include &lt;stdlib.h&gt;
  • sizeof(char) 在 C 中定义为 1,所以我会在 malloc 中忽略它 打电话。

除了这些,我觉得这个功能还不错。感谢您检查和报告错误。

【讨论】:

  • 就是这样。谢谢您的帮助。我一直盯着这段代码很久了,我什至忘记检查了。
  • 在没有任何帮助的情况下追踪这总是一个有趣的错误。
猜你喜欢
  • 2013-05-18
  • 2011-04-18
  • 2016-07-24
  • 2014-11-30
  • 1970-01-01
相关资源
最近更新 更多