2012-10-06 37 views
0

我需要創建一個完全通用的鏈表,它可以包含任何類型的通過一個枚舉指定的數據...如何將值賦給由指針算術計算出的內存地址?

的列表的節點具有以下結構:

__________________ 
    |_____|_____|_____| 

第一字段是包含存儲信息類型的sizeof(nodeType)字節。下一個字段的地址包含信息變量的地址。接下來的字段可以是一個簡單的節點或另一個鏈接列表中的下一個節點的地址..

基本上,我有一個節點類型枚舉:

typedef enum{ 
    STRING, INT, NIL, LIST 
} nodType; 

我已分配的內存節點像這樣的指針:

nodeType* node = malloc(sizeof(nodeType) + 2*sizeof(char*)); 

第一個sizeof(nodeType)字節包含存儲的inofrmation的類型。我分配它的值STRING由表達式:

*node = STRING; 

現在,我想在未來的sizeof(字符*)字節存儲一個char *指針的地址。 (所有指針都是一臺機器上同樣大小的(是的,ACC給我)?)。所以,我分配一個值給它喜歡:

char* str = strdup("Hello"); 
(char**)(char*(node) + sizeof(nodeType)) = &str; 

但是GCC標誌一個錯誤賦值運算符的LHS是不是一個左值.. 我需要爲該地址分配值,以便繼續構建該列表。 是否有一些優雅的方式在c使用結構?

回答

4

你忘了提領:

*(char***)((char*)node + sizeof(nodeType)) = &str; 

取消引用操作的結果始終是一個左值。在一般情況下,如果你想治療內存LO ­ CA ­重刑p,如果它指出T類型的變量,你需要將其轉換爲T *和間接引用:

*(T*)(p) = my_t_value; 

這適用於您的情況對於T = char **p = (char *) node + sizeof(nodeType)


但是,這僅僅是可怕的設計。沒有理智可以包含***。此外,通過假設所有元素都在內存中連續運行,可能會違反對齊約束條件。一個多SIM ­ PLER的方法是這樣的:

struct Node 
{ 
    struct Node * next; 

    nodType type; 
    void * data; 
}; 

用法:

struct Node * p = malloc(sizeof *p); 
p->next = NULL; 
p->type = STRING; 
p->data = str; 

請注意,我選擇了直接存儲字符串作爲char *,並不是作爲指針char *。這個主題應該是列表節點擁有p->data,並且應該說節點­ moval無條件地free(p->data);

+0

儘管我已經在自己的代碼中使用了至少'*****'(甚至可能是'******'),但我同意它並不特別理智(或必要,一次我學到了更多的技巧)。任何_that_複雜的東西都應該被埋在一個'struct'中,甚至可以通過線性化複雜的數組類型對象來簡化事情。 –