使用 malloc (C89) 在 main() 之外初始化结构 [重复]
Posted
技术标签:
【中文标题】使用 malloc (C89) 在 main() 之外初始化结构 [重复]【英文标题】:Initializing a struct outside of main() using malloc (C89) [duplicate] 【发布时间】:2017-05-17 14:24:02 【问题描述】:我正在尝试在 C 中实现一个双向链表,我需要使用一个初始化函数,同时保持一个大小字段。我的代码如下:
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;
当我尝试在 init 函数中访问 list->size 时,我得到了正确的值,但是当我尝试从 main 访问 list->size 时,程序返回一个奇怪的大负值(可能是一个地址十六进制)。
想知道我做错了什么。包含标准库。
【问题讨论】:
我没有得到反对票。提供的代码是一个明确的问题。 【参考方案1】:您只是在修改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;
【讨论】:
这行得通,但是我应该如何实现函数签名:void init(linkedlist* list) 我被限制在? 你不能——你要么使用上面的方法,要么使用@dbush的方法,或者你在init
之外执行malloc
(或等效)(例如在main
中),这样list
指针就不会被修改。
很好,我会继续努力的 - 谢谢
另一个让我烦恼的问题 - 我为什么可以修改结构的值(就像在 init 函数上所做的那样),而它还没有分配到内存中的任何地方?
@Triumphan:C 是一种低级语言,它为你提供了无数种不同的方式来让你自食其果。永远不要仅仅因为某件事看起来起作用,就认为这样做是正确的。【参考方案2】:
在 C 中,所有参数都是按值传递的。所以init
中的list
变量是main
中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;
【讨论】:
以上是关于使用 malloc (C89) 在 main() 之外初始化结构 [重复]的主要内容,如果未能解决你的问题,请参考以下文章