从函数传递一块内存

时间:2009-09-28 06:59:42

标签: c function malloc pass-by-reference

我正在试图弄清楚如何在函数中分配一块内存,并通过其中一个参数传回指向该块的指针。这是一个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

我做错了什么?

7 个答案:

答案 0 :(得分:5)

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

  

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

(强调我的。)

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

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

    /* code here */

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

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

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

答案 1 :(得分: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并通过更改变量类型或通过显式转换。我还在适当的地方添加了对变量声明的初始化。)

答案 2 :(得分:3)

好吧,假设(int)缓冲区应该是(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);
}

答案 3 :(得分: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()的作用。选择最具逻辑意义的那个。

答案 4 :(得分:1)

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

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

甚至更好,像这样回归:

void char * foo(int memsize)
{

}

答案 5 :(得分: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);
}

答案 6 :(得分:0)

还有一个简化:

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


int main()
{
  char *foo = (char *) fun();
  printf("\n%p\n",foo);
}