0

我试图弄清楚如何在函数中分配一块内存并通过其中一个参数传回指向该块的指针。这是一个 C 程序。我似乎遇到了一些麻烦。这是代码:

void foo(char *ptr)
{
     if (!(ptr = malloc(size)))
          printf("error");

     /* code here */

     printf("buffer address: %i\n", (int)buffer);
}

int main()
{
     char *ptr;
     ptr = NULL;

     foo(ptr);

     printf("buffer address: %i\n", (int)buffer);
}

结果是:

buffer address: 142385160
buffer address: 0

但我期待的是:

buffer address: 142385160
buffer address: 142385160

我究竟做错了什么?

4

7 回答 7

5

其他人已经显示将指针传递给指针,但您的问题指出了一个更简单的选项:

我试图弄清楚如何在函数中分配一块内存并返回一个指向该块的指针。

(强调我的。)

当您考虑返回某些东西时,请尝试将其用作返回值 :)

char* foo()
{
    char* ptr;
    if (!(ptr = malloc(size)))
        printf("error");

    /* code here */

    printf("buffer address: %i\n", (int)ptr);
    return ptr;
}

(您也可以考虑返回void*而不是char*

如果由于其他原因您已经有了返回值,那么使用“指向指针的指针”方法可能是合适的 - 但如果您不使用原始值,只是返回一些东西,我相信保持简单是值得的如果你可以的话。

于 2009-09-28T07:05:39.683 回答
3

你为什么不只返回一个指针,就像你的问题所说的那样:

void* foo(void)
{
     void* ptr = malloc(size);
     if (!ptr)
          printf("error");

     /* code here */

     printf("buffer address: %p\n", ptr);
}

int main(void)
{
     char *ptr = foo();

     printf("buffer address: %p\n", (void*)ptr);
}

(我所做的其他编辑是确保所有printf指针类型都使用%p并传递了一个void*类型,要么通过更改变量的类型,要么通过显式强制转换。我还在适当的地方添加了变量声明的初始化。)

于 2009-09-28T07:05:45.083 回答
3

好吧,假设 (int)buffer 应该是 (int)ptr,你是通过值而不是引用传递指针,所以在函数中进行的更改对外部没有影响。

您可以返回结果:

char *foo()
{
     if (!(ptr = malloc(size)))
          printf("error");

     /* code here */

     printf("buffer address: %i\n", (int)ptr);
     return ptr;
}

int main()
{
     char *ptr;
     ptr = NULL;

     ptr = foo();

     printf("buffer address: %i\n", (int)ptr);
}

或通过引用传递指针

void foo(char **ptr)
{
     if (!(*ptr = malloc(size)))
          printf("error");

     /* code here */

     printf("buffer address: %i\n", (int)*ptr);
}

int main()
{
     char *ptr;
     ptr = NULL;

     foo(&ptr);

     printf("buffer address: %i\n", (int)ptr);
}
于 2009-09-28T07:05:46.063 回答
2

指针是变量。C 中的所有变量都是按传递的。观察:

void test(int i)
{
    printf("Before: %i\n", i);
    i = 0;
    printf("After:  %i\n", i);
}

int main(void)
{
    int i = 5;
    printf("Before: %i\n", i);
    test(i);
    printf("After:  %i\n", i);
}

印刷:

Before: 5
Before: 5
After:  0
After:  5

指针的工作方式相同。更改指针本身不会更改调用者的指针。指针的好处是改变指针的内容。你有几个选择:

void foo(char **ptr)
{
    if (!(*ptr = malloc(size)))
        printf("error");

    /* code here */

    printf("buffer address: %p\n", ptr);
}

int main()
{
    char *ptr;
    ptr = NULL;

    foo(&ptr);

    printf("buffer address: %p\n", *ptr);
}

或者:

char *foo(char *ptr)
{
    if (!(ptr = malloc(size)))
        printf("error");

    /* code here */

    printf("buffer address: %p\n", ptr);
    return ptr;
}

int main()
{
    char *ptr;
    ptr = NULL;

    ptr = foo(ptr);

    printf("buffer address: %p\n", ptr);
}

你使用哪个取决于做什么foo()。选择一个最合乎逻辑的。

于 2009-09-28T07:06:14.283 回答
1

您需要将指针传递给指向 char 的指针,如下所示:

void foo(char **ptr)
{
  // ...
  *ptr = result of malloc;
}

或者更好的是,像这样返回:

void char * foo(int memsize)
{

}
于 2009-09-28T07:01:58.160 回答
1

在您的函数中,您重新分配指针的本地副本。要在调用函数中重新分配指针,您需要将指针的地址传递给它,而不是指针指向的地址。

void foo(char **ptr)
{
     if (!(*ptr = malloc(size)))
          printf("error");

     /* code here */

     printf("buffer address: %i\n", (int)*buffer);
}

int main()
{
     char *ptr;
     ptr = NULL;

     foo(&ptr); // pass address of your ptr, rather than it's value

     printf("buffer address: %i\n", (int)buffer);
}
于 2009-09-28T07:02:44.650 回答
0

另一种简化可能是:

void *fun()
{
  return(malloc(sizeof(char)));
}


int main()
{
  char *foo = (char *) fun();
  printf("\n%p\n",foo);
}
于 2009-09-30T09:30:28.897 回答