Условный переход или перемещение зависит от неинициализированных значений? - PullRequest
2 голосов
/ 04 мая 2011

Я получаю следующую ошибку при запуске моей программы на С:

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

1 Ответ

6 голосов
/ 04 мая 2011

Ваша функция createEntry не инициализирует поле next. Фактическая точка, где что-то используется в унифицированном виде, находится за пределами кода, который вы показали (в строке 214 search.c), но из того, что вы показали, я думаю, будет поле next.

Некоторые другие щупальца:

  • Часто бывает сложно скрыть указатель внутри typedef. Это делает неясным для Читатель, забыли ли вы использовать указатель или нет. Иногда это непонятно писатель тоже, что приведет к ошибке. Таким образом, я рекомендую вам изменить Entry typedef быть таким: typedef struct Entry_ Entry;
  • Подчеркивание в конце имени структуры излишне и выглядит как опечатка. Таким образом, было бы лучше назвать это просто struct Entry.
  • В C нет необходимости типизировать результат malloc, и это может скрыть пропал без вести #include <stdlib.h>
  • sizeof(char) по определению 1 в C, поэтому я бы оставил это в malloc позвонить.

Кроме этих вещей, функция выглядит хорошо для меня. Престижность для проверки и сообщения об ошибках.

...