C-Can';t初始化作为参数传递的指针 #包括 #包括 类型定义结构{ 无符号长度; }名单; void init(列表*l){ l=(列表*)malloc(sizeof(列表)); l->长度=3; } 内部主(空){ List*List=NULL; init(列表); 如果(列表!=NULL){ printf(“最终长度%d\n”,列表->长度); 返回0; } 返回1; }

C-Can';t初始化作为参数传递的指针 #包括 #包括 类型定义结构{ 无符号长度; }名单; void init(列表*l){ l=(列表*)malloc(sizeof(列表)); l->长度=3; } 内部主(空){ List*List=NULL; init(列表); 如果(列表!=NULL){ printf(“最终长度%d\n”,列表->长度); 返回0; } 返回1; },c,pointers,parameters,constructor,struct,C,Pointers,Parameters,Constructor,Struct,这是给我带来问题的代码的简化版本。我试图从一个方法构造指针*list,其中*list作为参数传递 我知道我可以通过将voidinit(List*l)更改为voidinit(List**l)使其工作,但这是一个课堂教程。我无法更改方法参数。我花了四个小时做这个 在我面对教授之前,我想确保没有办法使void init(List*l)起作用 提前感谢您正在将指针的副本传递给init,它正在分配内存,将其存储在本地副本中,并在init返回时立即泄漏。不能以这种方式将数据传递回调用函数。您需要返回分配的数

这是给我带来问题的代码的简化版本。我试图从一个方法构造指针
*list
,其中
*list
作为参数传递

我知道我可以通过将
voidinit(List*l)
更改为
voidinit(List**l)
使其工作,但这是一个课堂教程。我无法更改方法参数。我花了四个小时做这个

在我面对教授之前,我想确保没有办法使
void init(List*l)
起作用


提前感谢

您正在将指针的副本传递给
init
,它正在分配内存,将其存储在本地副本中,并在
init
返回时立即泄漏。不能以这种方式将数据传递回调用函数。您需要返回分配的数据,或者传入指向要修改的指针的指针,这两种操作都涉及修改函数签名

#include <stdio.h>
#include <stdlib.h>
typedef struct {
    unsigned length;
} List;
void init(List *l) {
    l = (List *) malloc(sizeof(List));
    l->length = 3;
}
int main(void) {
    List *list = NULL;
    init(list);
    if(list != NULL) {
        printf("length final %d \n", list->length);
        return 0;
    }
    return 1;
}
作业是否指定您必须从
init
中分配
列表
?如果没有,则始终可以将指针传递到已分配的
列表
对象,并执行以下项的任何初始化
length=3
占位符:

void init(List **l) {
    *l = (List *) malloc(sizeof(List));
    (*l)->length = 3;
}

init(&list);

问题是指针是按值传递的,因此您需要放弃更改。您确实需要一个指向指针的指针才能正确执行此操作。就像你会做的那样:

void init(List *l) {
  l->length = 3;
}

List list;
init(&list);
printf("length final %d \n", list.length);
当您调用它时,您将使用
init(&list)
而不是
init(list)
。当然,在这种情况下,直接返回结果而不是使用指向指针的指针是有意义的:

void init(List** l) {
   *l = (List*) malloc(sizeof(List));
   // ...
}
然后,使用上面的代码,您可以简单地使用
list=init()

<>注意,C++中,可以使用引用代替指针,但是混合引用和指针是非常混乱的。在这里,使用返回类型确实是最整洁的事情


如果您必须使用现有的签名,您可以偷偷地初始化列表,然后在
init()
函数中,您可以使传入列表的下一个指针指向实际要创建的列表。然后,在调用
init()
之后,您可以使用下一个指针并处理您创建的原始列表对象。或者你可以通过一些虚拟元素来获得第一个元素。

这个作业可能是在课堂上教授传递值和传递引用的一个好方法。如果要维护构造函数的签名,需要修改main函数

List* init() {
    List* result = (List *) malloc(sizeof(List));
    result->length = 3;
    return result;
}
#包括
#包括
#包括
类型定义结构{
无符号长度;
}名单;
void init(列表*l){
l->长度=3;
}
内部主(空){
List;//x=NULL;
memset(&list,0,sizeof(list));
初始化(&列表);
printf(“最终长度%d\n”,列表长度);
返回1;
}
现在这里的列表是列表类型,而不是列表地址。init()方法传递了list的地址,在init中可以更改结构内容的值

/a.out


需要向length final 3

init传递指向现有列表的指针。我怀疑这里真正的问题在于您的数据结构。你有一个叫做列表的东西,它包含一个长度,但是在任何地方都看不到列表。列表可能应该包含一个指向给定长度数组的指针,init应该malloc该数组并设置指针。当你要求教授纠正他没有违反的要求时,你可能会发现这一点——如果是的话,他可能已经从过去的学生那里听说了,并且现在已经纠正了。

PO特别提到了是否可以避免“void init(List**l)”的问题赋值没有指定它必须是构造函数。我将给我的教授发电子邮件,请他改变要求。谢谢你的帮助!我认为MeMSET是对封装的违反。init负责初始化列表的内容;如果需要一个memset,它应该这样做。事实上,它是不需要的。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
    unsigned length;
} List;


void init(List *l) {
    l->length = 3;
}
int main(void) {
    List list;// x = NULL;
    memset(&list,0,sizeof(List));
    init(&list);
    printf("length final %d \n", list.length);
    return 1;
}