2017-01-11 4 views
1

私は、非同種のリストのように、任意のデータ型を受け入れることができるリンクリストを作成しようとしています。だからここ構造体ポインタがデータを失う

#define CNode malloc (sizeof(listnode)); 
#define CNodeContent malloc (sizeof(content)); 

typedef enum datatypes { 
    CHAR, 
    INT , 
    FLOAT, 
    STRING, 
    LIST 
}datatype; 

typedef struct contentInfo { 
    void *data; 
    datatype type; 
}content; 

typedef struct node { 
    content* val; 
    struct node *next; 
} listnode; 

typedef listnode* list; 


// Creating content 
//---------------------------------------------------------------------------------------------- 

content* createContentInt(int val) { 
    content *newContent = CNodeContent; 
    newContent->type= INT; 
    newContent->data = &val; 
    return newContent; 
} 

content* createContentFloat(float val) { 
    content *newContent = CNodeContent; 
    newContent->type= FLOAT; 
    (newContent->data) = &val; 
    return newContent; 
} 

content* createContentChar(char val) { 
    content *newContent = CNodeContent; 
    newContent->type= CHAR; 
    newContent->data = &val; 
    return newContent; 
} 

content* createContentString(char* val) { 
    content *newContent = CNodeContent; 
    newContent->type= STRING; 
    newContent->data = val; 
    return newContent; 
} 

//--------------------------------------------------------------------------------------------- 

// List Functions 

list createList(content *cont) { 
    list newnode = CNode; 
    printf("\n--%d--value: %d ",(cont->type),*((int*)cont->data)); 
    newnode->val = cont; 
    printf("<leh %d >",(newnode->val->type)); 
    newnode->next= NULL; 
    return newnode; 
} 
int main() { 
    list llist = createList(createContentInt(4)); 
    content * c = createContentInt(5); 
    printf("Main-> %d <",(*(int*)c->data)); 
    createList(c); 
    /* append(llist,c); */ 
    /* display(llist); */ 
    /* append(llist,createContentInt(5)); */ 
    /* append(llist,createContentInt(6)); */ 
    /* display(llist); */ 
    return 0; 
} 

が問題である:

私はcreateContentInt(4)を呼び出すと、それは、適切にコンテンツノードを返し しかし、すぐに私に同じコンテンツノードとのコールcreateListまたはappend機能として、値data0に設定されています。

戻り値をcreateContentIntから確認しましたが、createListまたはappendの場合を除いてすべて正常に動作しません。

さらに、content->typeにも適切な値がありますが、dataが失われています。

私はこのフォーラムでの検索で何度も苦労しましたが、値が0 に設定されている理由を見つけることができませんでした。

newContent->data = (int*)4; 

コードが正常に動作します:私は考え出した もう一つは、私はこのようなものを使用している場合です。違いはなんですか?

誰かが、なぜ機能していないのかについてのいくつかの洞察をお願いします。 それ以外の解決策は非常に高く評価されますが、私はなぜそれが機能していないのかを知る傾向があります。

+6

ベースの変数をスタックするための参照を取得™悪い考えです。 – Lou

+0

@Lousyあなたは議論をしていただけますか? –

+0

'newContent-> data = &val;'は 'val'のアドレスを格納します。 'createContent ***'関数から返ってきたときに 'val'に何が起こるか考えてみましょう。破壊され、あなたのアドレスは無効です。 – user694733

答えて

3
newContent->data = &val; 

あなたは(スタックにある)あなたの関数のパラメータのアドレスでdataを割り当てています。

valを保持するレジスタを連続呼び出しで再使用すると、dataの内容が上書きされます。

さらに一般的には、機能を終了するとvalのアドレスを余裕で再利用できるので、dataはごみを指します。

ではなく、あなたは、例えば可能性:

newContent->data = malloc(sizeof(TYPE)); // Set TYPE to INT/CHAR/... 
// test return of malloc 
memcpy(newContent->data, &val, sizeof(TYPE)); 
// Note that you will need an extra function to free() the allocated memory 
関連する問題