我是第一次用C语言编写程序。我对C ++有很多经验,但是C对指针的依赖以及缺少new
和delete
真的让我失望。我定义了一个简单的数据结构,并编写了一个初始化它的函数(通过获取指针)。这是我的代码:
//in Foo.h
#include <stdio.h>
#include <stdlib.h>
typedef struct Foo {
struct Foo * members[25] ;
} Foo ;
void foo_init(Foo * f) ;
void foo_destroy(Foo * f) ;
//in Foo.c
void foo_init(Foo * f) {
f = (Foo*)malloc(sizeof(Foo));
for (size_t i = 0 ; i < 25 ; i++) {
f->members[i] = NULL ;
}
}
//define foo_destroy()
//in main.c
#include "Foo.h"
int main(int argc, const char * argv[])
{
Foo * f ;
foo_init(f) ;
/* why is f still NULL here? */
foo_destroy(f) ;
/* ... */
return 0;
}
当我在foo_init()
(指向f
结构的指针)上测试Foo
函数时,在函数返回后它为null。 f
内的指针foo_init()
初始化得很好,但是,我不认为这是init函数本身的问题。在黑暗中拍摄,但这可能与C处理价值/通过参考传递的方式有关(我仍然不完全掌握)?我怎么能纠正这个?
答案 0 :(得分:3)
1)你在for循环中越界了(正如@ user3121023更改为25
所指出的那样)
2)你是(m)为局部变量分配空间,使用:
Foo *foo_init(void) {
Foo *f = malloc(sizeof(Foo)); /* don't cast malloc */
for (size_t i = 0 ; i < 25 ; i++) {
f->members[i] = NULL ;
}
return f;
}
和main
:
f = foo_init();
答案 1 :(得分:1)
void foo_init(Foo* f)
在C中,参数按值传递。在这里,您传递名为f
的参数,类型为Foo*
。在您分配给f
的函数中。但是,由于参数是按值传递的,因此您将分配给本地副本,该副本是该函数的私有副本。
为了让调用者看到新分配的结构,您需要额外的间接级别:
void foo_init(Foo** f)
{
*f = ...;
}
在通话现场:
Foo* f;
foo_init(&f);
现在,由于您的函数旨在向调用者发送新值,并且您的函数当前具有void
返回值,因此将新值返回给调用者会更有意义。像这样:
Foo* foo_init(void)
{
Foo* foo = ...;
return foo;
}
你会这样称呼:
Foo* f = foo_init();
答案 2 :(得分:1)
在函数void foo_init(Foo * f)
中传递指针。现在,此指针在此函数中作为值传递,并且函数内部对此变量的修改不会反映在此函数之外。换句话说,函数foo_init中的变量f是局部变量。
所以你应该通过这样做来返回f的值:
Foo* foo_init(Foo * f)
{
f = (Foo*)malloc(sizeof(Foo));
for (size_t i = 0 ; i < 25 ; i++) {
f->members[i] = NULL ;
}
return f;
}
除了这个注释,我已经改变了for循环中的条件。您已分配了25个对象的数组。所以你的for循环应该从0到24。
并且主要是
f = foo_init();