使用 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 变量是mainlist 的值的副本,并且正在修改的是该副本。所以在函数之外看不到变化。

您需要将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() 之外初始化结构 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

以下程序在 C89 模式下编译时如何输出“C89”,在 C99 模式下编译时如何输出“C99”?

C89:论结构体/枚举体/联合体的使用

C89:论IO内存

c语言main啥意思?

在子函数中应用malloc函数

如果两种类型不相同,则导致 C89 中的编译错误