2016-09-04 10 views
2

私はC言語を使い慣れていますが、私はよくある問題を抱えていますが、私の場合はその理由を理解できません。エラー:条件ジャンプまたは移動が初期化されていない値に依存する - C valgrind

このメソッドは、指定された名前のMapを初期化し、それがRED-BLACKツリーに存在するかどうかを確認することを目的としています。

void reduceMap(char *mapName){ 

    Map *tempMap = (Map *) malloc(sizeof(Map)); 
    struct rbNode *tempNode = (struct rbNode *) malloc(sizeof(struct rbNode)); 

    copyName = stringCopy(mapName); 

    tempMap->name = copyName; 
    tempNode->data = tempMap; 

    ...DO SEARCH HERE... 

    freeMap(tempNode); 

} 

だから私は地図が含まれているノードのメモリを割り当て、研究を行うと、最終的に作成された一時オブジェクトのメモリを解放します。私のオブジェクトの構造は次の通りである。

typedef struct{ 
    char *name; 
    char *specification; 
    Point *start, *end; 
}Map; 

struct rbNode{ 
    Color color; 
    void *data; 
    struct rbNode *parent, *leftChild, *rightChild; 
}; 

方法stringCopyとfreeMapは、次のとおりです。

void freeMap(struct rbNode *node){ 
    if(node){ 

     free(((Map *)node->data)->name); 

     if(((Map *)node->data)->specification != NULL) 
      free(((Map *)node->data)->specification);   

     free((Map *)node->data); 
     free(node); 
    } 
} 


char *stringCopy(const char *source){ 
    char *copy = (char *)malloc(strlen(source) + 1); 

    strcpy(copy,source); 
    return copy; 
} 

私はvalgrindのを使用してプログラムをテストすることだし、これは私が取得エラーです:

Conditional jump or move depends on uninitialised value(s) 
==5215== at 0x8049DF3: freeMap (in /home/ve/Dropbox/progetto2016/Percorsi/percorsi) 
==5215== by 0x8048C40: reduceMap (in /home/ve/Dropbox/progetto2016/Percorsi/percorsi) 
==5215== by 0x80489DA: main (in /home/ve/Dropbox/progetto2016/Percorsi/percorsi) 
==5215== Uninitialised value was created by a heap allocation 
==5215== at 0x402C17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==5215== by 0x8048B0A: reduceMap (in /home/ve/Dropbox/progetto2016/Percorsi/percorsi) 
==5215== by 0x80489DA: main (in /home/ve/Dropbox/progetto2016/Percorsi/percorsi) 

私はこの問題がtempMapの割り当てによって発生していることを理解していますが、それは何も初期化されていないようですが、なぜですか?私は名前と仕様だけを気にします...私は本当に理解していません。

助けていただければ幸いです。 が

+1

注:Cでは_methods_はサポートされず、_functions_はサポートされません。そして、あなたは 'malloc'&friendsの結果をキャストすべきではありません。 – Olaf

+0

ありがとうございました@Olafはそれを指摘しました – VeVeVez

答えて

2

は、簡単に言えばありがとう、あなたのreduceMapで、これはあなたが全体のstructを割り当てられて初期化されません

Map *tempMap = (Map *) malloc(sizeof(Map)); 
tempMap->name = copyName; 
tempMap->specification = /* what!?? */; 

起こるようです。デストラクタ(freeMap)に一致するようにマップコンストラクタ(initMap関数の形式)を記述することを検討してください。

サイドノートDon't cast the result of mallocです。

+0

@StoryTellerありがとうございました。構造体のchar *のデフォルト値は自動的にNULLになり、NULLを使った評価(Map *)ノード - >データ) - >仕様は問題ではないと思った – VeVeVez

+1

@VeVeVez、それは要件ではありません。その値は、明示されていません。それが何かに依存することは、未定義の動作に依存しています。残念なことに、多くのデバッガでは、特定のビルド構成でメモリを初期化しないため、バグを追跡しにくい場合があります。 – StoryTeller

1

あなたはマップに

typedef struct{ 
    char *name; 
    char *specification; 
    Point *start, *end; 
} Map; 

を仕様メンバを初期化しませんが(if文)後に、あなたは条件付きでジャンプして、このいないに関わらず値を使用します。

if(((Map *)node->data)->specification != NULL) 

SOLUTION

のすべてのメンバーを初期化しますそれらを使用する前にMap

+0

ありがとう@where_is_tftp、私はポイントを理解しているなら、私は自由な関数で使用する/評価する予定のすべてのフィールドを初期化する必要があります。 構造体の 'char * specification'のデフォルト値が自動的にNULLで、'(Map *)node-> data) - > specification'をNULLで評価することは問題ではないと思っていました... my fault – VeVeVez

+1

@VeVeVez It初期化されていない変数を使用するためにCで未定義の動作です。このルールを覚えています。ヒープ上に割り当てられたC変数は、初期化されていない変数とローカル変数です。使用前に初期化する必要があります。 – 4pie0

関連する問題