函数中使用的malloc的范围

时间:2010-09-02 16:21:52

标签: c malloc

当函数返回时,通过malloc分配的内存是否被释放?或者仍然可以使用指针在main()函数中访问它?

例如

void function(int *a)
{
    a=(int *)malloc(sizeof(int));
    *a=10;
}
int main()
{
    int *num;
    function(num);
    printf("%d",*num);
    return(0);
}

存储在a中的整数可以由main()访问吗?

6 个答案:

答案 0 :(得分:36)

不,当您从函数中退出范围/返回时,不会释放分配有malloc的内存。

你有责任释放你的malloc记忆。

在你的情况下,内存在main()中是不可访问的,但那是因为你只处理一个局部变量。

void function(int *a)
{
    a=(int *)malloc(sizeof(int));

此处,afunction中的局部变量。指针在C中按值传递,因此当a时,function(num);会在main中收到指针的副本。(main)没有看到您指定指针的本地副本。

你必须这样做:

void function(int **a)
{
  *a= malloc(sizeof(int));
  **a=10;
}
int main()
{
  int *num;
  function(&num);
  printf("%d",*num);
  free(num);
  return(0);
}

int* function(void)
{
  int *a= malloc(sizeof(int));
  *a=10;
  return a;
}
int main()
{
  int *num;
  num = function();
  printf("%d",*num);
  free(num);
  return(0);
}

答案 1 :(得分:3)

仅当您在其上调用malloc()时,才会释放

free()内存。任何拥有有效指针的人都可以访问它,直到那个时间。

答案 2 :(得分:3)

没有。您按值传递指针num,因此function所做的更改不会反映在main中。因此,有效地无法从main

访问/释放分配的内存

要解决此问题,您可以传递num的地址或从函数返回a并在num中收集返回的值

答案 3 :(得分:1)

malloc工作正常(尽管你必须在它返回的指针上调用free())。这里的问题是你没有返回指向它分配的内存的指针。

“int * a”,函数()的参数是整数的地址。返回的常用方法是重写函数,如下所示:

int * function()
{
  int * a = (int *)malloc(sizeof(int));
  *a = 10;
  return a;
}

要通过参数返回它,您需要返回指针的地址:

//  pp points to a pointer
void function( int ** pp )
{
    //  Assign allocated memory to the thing that pp points to
    *pp = (int *)malloc( sizeof( int ) );

    //  Get the thing pp points to -- a pointer.
    //  Then get the thing which THAT pointer points to -- an integer
    //  Assign 10 to that integer. 
    **pp = 10;
}

void main()
{
    int * p = NULL;

    function( & p );

    printf( "%d\n", *p );

    free( p );
}

现在你知道他们为什么发明了C#。

这是一种重写分配事物的方法,因此更清楚:

void function( int ** pp )
{
    int * newmemory = (int *)malloc( sizeof( int ) );

    //  Assign 10 to the integer-sized piece of memory we just allocated. 
    *newmemory = 10;

    //  Assign allocated memory to the thing that pp points to. 
    *pp = newmemory;
}

答案 4 :(得分:0)

内存未被释放。任何函数都可以分配内存,任何其他函数都可以解除分配。如果你不是超级挑剔,直到......有人发明了垃圾收集,这真是一团糟。

答案 5 :(得分:0)

您可以将已分配内存的直接地址存储在列表容器中,然后创建一个循环函数,将每个地址访问为自由函数,然后弹出该地址。您可以将地址直接插入免费功能,如free(myaddresslist.front()); myaddresslist.pop_front();。这是一种自行完成垃圾收集的准方法,无需将整个项目更改为基于GC的语言。使用myaddresslist.size()确保您不会在空字段上调用free()(导致崩溃)并确定要执行的循环次数。