C语言 当释放结构变量时,结构内部的指针会自动释放吗?

qqrboqgw  于 2023-01-29  发布在  其他
关注(0)|答案(4)|浏览(288)

我有这样的东西:

struct Pos {
    float x, y;
};
struct Rect {
    struct Pos* pos;
    int width, height;
};

我已经创建了一个指针Rect,那么当我使用free()释放这个指针时,它也会释放pos吗?

olmpazwi

olmpazwi1#

假设你做了

struct Rect *r = malloc( sizeof *r );
r->pos = malloc( sizeof *r->pos );
...
free( r );

则否,这 * 不会 * 释放r->pos指向的内存。您必须确保在释放r之前释放r->pos

free( r->pos );
free( r );

对于需要多次分配和释放操作的类型,抽象出分配和释放通常是一个好主意:

struct Rect *newRect( void )
{
  struct Rect *r = malloc( sizeof *r );
  if ( r )
  {
    r->pos = malloc( sizeof *r->pos );
    /**
     * If we can't successfully allocate r->pos, 
     * deallocate anything we've allocated
     * so far and return NULL.
     */
    if ( !r->pos )
    {
      free( r );
      r = NULL;
      fputs( "Failed to allocate internal member\n", stderr );
    }
  }
  return r;
}

void freeRect( struct Rect *r )
{
  free( r->pos );
  free( r );
}
xu3bshqb

xu3bshqb2#

不需要;手动分配的所有内容都需要手动释放。这使得动态2D(或更多)数组的编码有些繁琐,需要:

int **array = malloc(NUM_ROWS * sizeof(int *));
 if(NULL == array)
 {
     // Handle out of memory error
 }
 for(int i = 0; i < NUM_ROWS; i++)
 {
     array[i] = malloc(NUM_COLS * sizeof(int));
     if(NULL == array[i])
     {
         // Handle out of memory error
     }
 }

若要分配,则:

for(int i = 0; i < NUM_ROWS; i++)
{
    free(array[i]);
    array[i] = NULL;
}
free(array);
array = NULL;

如果你手动分配pos,那么在释放其父结构体Rect之前手动释放pos,如果它在:

free(someRect.pos);
someRect.pos = NULL;
free(someRect);
someRect = NULL;

我总是在free ing或delete ing(C++)之后设置指向NULL(ptr)的指针。

flvtvl50

flvtvl503#

我已经创建了一个矩形指针,那么当我使用free()释放这个指针时,它也会释放pos吗?
假设指向struct Rect的指针是通过内存分配函数之一在堆上分配的(这样它就可以合法地成为free d),那么free()将只为所指向的结构释放内存,而不是嵌套的指针。
你必须先free()指针pos,然后free()指针struct,否则你将失去对通过pos分配的内存的访问,并泄漏它。
每个你malloc()的对象,都必须在以后随free()一起发布。它不会自动为你发生。
另请参阅:When you exit a C application, is the malloc-ed memory automatically freed?

bqucvtff

bqucvtff4#

注意,这是题外话,因为它没有回答你的主要问题。
但根据你的描述

  • “我创建了一个矩形指针”*

我想指出的是,使用这个指针变量而不必释放内存是 * 可能的 *,只需将它指向在堆栈上创建的一个位置即可,因此给出了您的定义,下面是它的工作原理:

struct Pos {
    float x, y;
};
struct Rect {
    struct Pos* pos;
    int width, height;
};

int main(void) {
   
    struct Rect rect = {0};//create instance of struct on stack
    struct Rect *pRect = &rect;//point pointer to location created on the stack
    pRect->pos = malloc(10*sizeof(struct Pos));// allocate only pointer
                                               // member of struct Pos
    if(pRect->pos)
    {
        //do something with rect.pos
        for(int i=0;i<10;i++)
        {
            pRect->pos[i].x = (i+1.0)*1.0; 
            pRect->pos[i].y = pRect->pos[i].x * pRect->pos[i].x;
        }
        //free rect.pos when finished
        free(pRect->pos);//only need to free the pointer member of struct Pos
        //no need to free pRect as it points to memory created on stack
    }
    return 0;
}

相关问题