2017-01-03 64 views
-2

我试图在C中实现一个双向链表,并且我需要使用初始化函数,同时保持大小字段。我的代码如下:使用malloc初始化main()之外的结构(C89)

typedef struct element{ 
    struct element* next; 
    struct element* prev; 
    int value; 
}element_t; 

typedef struct linkedlist{ 
    element_t* head; 
    element_t* tail; 
    int size; 
}linkedlist; 

void init(linkedlist* list){ 
    list = malloc(sizeof(linkedlist)); 
    list->size = 0; 
} 

int main(int argc, char** argv){ 
    linkedlist* list; 
    init(list); 
    return 0; 

当我试图访问列表 - >尺寸的初始化函数,我得到正确的值,但是当我尝试从主访问列表 - >尺寸程序返回一个奇怪的大负值(可能是十六进制的地址)。

想知道我做错了什么。包括stdlib。

+0

我没有得到反对票。所提供的代码是一个明确的问题。 – hetepeperfan

回答

5

您只修改list的本地副本,main永远不会看到。你可能想要做这样的事情:

linkedlist* init(void) { // <<< 
    linkedlist* list = malloc(sizeof(linkedlist)); // <<< 
    list->size = 0; 
    return list; // <<< 
} 

int main(int argc, char** argv){ 
    linkedlist* list = init(); // <<< 
    return 0; 
} 

如果你要保持原有功能的签名,那么你一定不能内init修改list。你可以这样做:

void init(linkedlist* /* const */ list){ 
    list->size = 0; 
} 

int main(int argc, char** argv){ 
    linkedlist list; //<<< 
    init(&list); //<<< 
    return 0; 
+0

这有效,但我应该如何实现函数签名: void init(linkedlist * list) 我仅限于? – Triumphan

+0

你不能 - 你要么使用上面的方法,要么使用@ dbush的方法,或者你在'init'之外(例如在'main')做'malloc'(或者等价的),这样'list'指针没有修改。 –

+0

很好,我会继续 - 谢谢 – Triumphan

2

在C中,所有参数都是按值传递的。因此init中的list变量是中的list的值的拷贝,并且正在修改该拷贝。所以这个改变在功能之外是看不到的。

您需要的list地址进入init,并更改函数接受一个指针到指针。

void init(linkedlist **list){ 
    *list = malloc(sizeof(linkedlist)); 
    (*list)->size = 0; 
} 

int main(int argc, char** argv){ 
    linkedlist *list; 
    init(&list); 
    return 0; 
}