函数层次结构和C指针初始化问题

时间:2011-08-19 08:55:49

标签: c pointers

我正在将我的一个项目从C ++转换为C,事情进展顺利,因为我没有使用很多C ++功能。但我遇到了一个特殊的问题,我已经设法在一个小的测试程序中复制了。这对我没有意义所以我会尝试用代码来解释。

typedef struct foo
{
    int num1;
    float num2;
    char* name;
}foo;

//This function allocates and initializes a foo object
foo* Initfoo()
{
    foo* f = malloc(sizeof(foo));
    f->num1 = 1024;
    f->num2 = 3.14;

    f->name = malloc(100);
    strcpy(f->name,"eleos re paidia");

    //Just before returning here by checking the f pointer we can see
    // it is initialized correctly
    return f;
}



 void afunctest(foo* f)
 {
    ///... suppose this function does stuff before ...

    //here it initializes the foo pointer
    f = Initfoo();
    ///...and after here suppose the function also does more stuff..

    //by checking at this point in the program the pointer is still initialized 
    //correctly to   what InitFoo initialized it to
    int asd =5;
 }


int main()
{

    foo* f = 0;

    //should do stuff and also initialize the foo* f
    afunctest(f);

    //when we check here the pointer f is still 0 as if afunctest() function never ran
    int asd = 5;

    return 0;
}

所以基本上用几句话来说,我们声明一个foo指针并将其初始化为零。然后我们将该指针传递给afunctest()函数,该函数应该执行操作并初始化它以供以后使用。在afunctest()函数内部,它似乎是正确初始化的,但是一旦我们回到main(),它仍然具有值0,就像函数从未运行一样。

起初我认为这是我原始程序中一个非常错综复杂的错误,因为它已经变得非常复杂但是能够在这里复制它意味着我遗漏了与C ++相比在C中使用指针的基本原理。你们有人能说出来吗?我究竟做错了什么?提前感谢您的任何反馈。

P.S。:我的编译器是Windows 7下的GCC。

3 个答案:

答案 0 :(得分:2)

您正在更改f的本地副本。这对调用者没有任何影响。

void afunctest(foo* f)
{
    f = Initfoo(); /* No effect for the caller of afunctest
}

尝试这样的事情:

void afunctest(foo **f)
{
    /* ... */
    *f = Initfoo();
}

/* In main. */
foo* f = 0;
functest(&f);

顺便提一下,还有C FAQ: Pass pointer Init

答案 1 :(得分:1)

C通过值传递。如果要从f内更改afunctest(),则需要将指针传递给它并操纵它指向的值。

例如:

#include <stdio.h>

static void fn (int x, int *y) {
    x = 42;     // Changes local copy of x, doesn't affect a.
    *y = 42;    // Changes value *pointed to* by local y (which is b in caller).
}

int main (void) {
    int a = 1;
    int b = 1;
    fn (a, &b); // Pass a and *address of* b.

    printf ("%d %d\n", a, b);
    return 0;
}

导致输出:

1 42

就您所拥有的代码而言,这将是:

void afunctest (foo **f) {
    *f = Initfoo();
}

int main (void) {
    foo* f = 0;
    afunctest (&f);
    return 0;
}

答案 2 :(得分:1)

解决方案实际上是直接安静 - 记住C总是按值传递所以当你在afunctest函数中设置f时,不会在主函数中更新你的f。

要做到这一点,你需要像这样使用** f:

void afunctest(foo** f)
 {

    //here it initializes the foo pointer
    *f = Initfoo();

 }

并称之为:

int main()
{

    foo* f = 0;

    //should do stuff and also initialize the foo* f
    afunctest(&f);

    return 0;
}