简体   繁体   English

为什么初始化函数返回null?

[英]Why is my initialization function returning null?

I'm writing a program in C for the first time. 我是第一次用C语言编写程序。 I have a good bit of experience with C++, but C's reliance on pointers and the absence of new and delete are really throwing me off. 我在C ++方面有丰富的经验,但是C对指针的依赖以及缺少newdelete的确使我失望。 I defined a simple data structure, and wrote a function that will initialize it (by taking a pointer). 我定义了一个简单的数据结构,并编写了一个将其初始化的函数(通过获取指针)。 Here's my code: 这是我的代码:

//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;
}

When I tested my foo_init() function on f (pointer to a Foo struct), it was null after the function returned. 当我在f (指向Foo结构的指针foo_init()上测试foo_init()函数时,该函数返回后为null。 The pointer f inside foo_init() is initialized just fine, however, so I don't think this is a problem with the init function itself. 指针f foo_init()初始化就好了,但是,我不认为这是与初始化函数本身就是一个问题。 Shot in the dark, but could this be related to the way C handles passing by value/passing by reference (something I still don't entirely have a grasp on)? 在黑暗中拍摄,但这可能与C处理值传递/引用传递的方式有关(我仍然不完全了解这一点)? How can I correct this? 我该如何纠正?

1) You go out of bounds in your for-loop, (as pointed out by @user3121023 change to 25 ) 1)您超出了for循环的范围(如@ user3121023所指出,更改为25

2) You are (m)allocating space for a local variable, use: 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;
}

and in main : 并且main

f = foo_init();
void foo_init(Foo* f)

In C parameters are passed by value. 在C中,参数按值传递。 Here you pass a parameter named f , of type Foo* . 在这里,您传递一个名为f的参数,类型为Foo* In the function you assign to f . 在函数中,您分配给f But since the parameter is passed by value, you are assigning to the local copy, private to that function. 但是由于参数是通过值传递的,因此您将分配给该函数专用的本地副本。

In order for the caller to see the newly allocated struct, you need an extra level of indirection: 为了使调用者能够看到新分配的结构,您需要额外的间接级别:

void foo_init(Foo** f)
{
    *f = ...;
}

And at the call site: 在呼叫站点:

Foo* f;
foo_init(&f);

Now, since your function is designed to send a new value to the caller, and your function currently has void return value, it would make more sense to return the new value to the caller. 现在,由于您的函数旨在将新值发送给调用方,并且您的函数当前具有void返回值,因此将新值返回给调用方会更有意义。 Like this: 像这样:

Foo* foo_init(void)
{
    Foo* foo = ...;
    return foo;
}

You would call this like so: 您可以这样称呼:

Foo* f = foo_init();

In function void foo_init(Foo * f) you are passing a pointer. 在函数void foo_init(Foo * f)您正在传递一个指针。 Now this pointer is passed as value in this function and modifications to this variable inside the function will not be reflected outside this function. 现在,此指针作为该函数中的值传递,并且对该函数内部对该变量的修改不会反映在该函数外部。 In other words the variable f in function foo_init is a local variable. 换句话说,函数foo_init中的变量f是局部变量。

so you should return the value of f by doing: 因此,您应该通过执行以下操作来返回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;
}

Apart from this note that I have changed the condition in for loop. 除了此注释之外,我还更改了for循环中的条件。 You have allocated array of 25 objects. 您分配了25个对象的数组。 So your for loop should go from 0 to 24. 因此,您的for循环应从0到24。

and in main you should 基本上你应该

f = foo_init();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM