如何释放我需要的结构指针

时间:2016-09-25 17:34:22

标签: c

我试图避免代码中的内存泄漏。我需要取消分配pElement,line和pSecond,而不会丢失pImage中的值。因为我需要在打印功能中打印这些值。

我的add函数包含struct GraphicElement * pElements;,struct GraphicElement * pSecond ;, struct point point;。

我使用malloc为每个结构分配内存,然后添加值,然后将最终值传递给pImage。除了我总是最终遇到3次内存泄漏之外,我的所有其他功能都能完美运行。因为我没有自由(pSecond); .... free(pElement)... free(line);

如果我在函数退出之前和将值传递给pImage之后尝试释放它们。我的价值都被抹去了。

如何在本地添加函数中释放这些值?

struct Point
{
    int x, y;
};

struct Line
{  
    Point start;
    Point end;
};

struct GraphicElement
{
    enum{ SIZE = 256 };
    unsigned int numLines; //number of lines
    Line* pLines; //plines points to start and end
    char name[SIZE];
};

typedef struct
{
    unsigned int numGraphicElements;
    GraphicElement* pElements; //the head points to pLines
}   VectorGraphic;

void InitVectorGraphic(VectorGraphic*); //initializes pImage->pElement
void AddGraphicElement(VectorGraphic*); //Used to add
void ReportVectorGraphic(VectorGraphic*); // prints pImage contents
void CleanUpVectorGraphic(VectorGraphic*); //deallocates memory

1 个答案:

答案 0 :(得分:1)

  

如何在本地添加函数中释放这些值?

无法显式释放本地分配的内存。也不本地免费一些记忆。一旦释放,就无法访​​问内存插槽,并且内部存储的数据将丢失。

在C中,您有两个分配内存的选项:您可以在堆上或堆栈上分配它。堆上保留的内存插槽可以全局访问,并且在显式释放之前一直保留。堆栈上保留的内容仅在您保持创建的上下文内时才有效。

假设您执行以下代码:

void func()
{
  int   x = 3;    // [2]
  int * p = & x;  // [3]
}

int main()
{
  func();         // [1]

  // [4]
  return 0;
}

指令[2]将在堆栈上分配一些内存。第二个([3])将执行相同的操作,并将第一个变量的地址存储在新的内存插槽中。函数返回([4])后,将释放此内存。从图形上看,这是发生的事情:

       Context   STACK    Address
              +---------+      
              |         | 0xa1  
       main   |         | 0xa0            
              +---------+      

 [1]          +---------+ 
=====>        |         |          
       func   |         | 0xa2        
              +---------+
              |         | 0xa1
       main   |         | 0xa0
              +---------+

 [2]          +---------+
=====>        |         | 
       func   | 3       | 0xa2 <-- x 
              +---------+
              |         | 0xa1
       main   |         | 0xa0
              +---------+

 [3]          +---------+
=====>        | 0xa2    | 0xa3 <-- p
       func   | 3       | 0xa2 <-- x 
              +---------+
              |         | 0xa1
       main   |         | 0xa0
              +---------+

 [4]          +---------+
=====>        |         | 0xa1
       main   |         | 0xa0
              +---------+
  

所以如果我在函数中使用malloc。一旦我存在该函数,堆上分配的内存会自动释放吗?

恰恰相反。如果使用像malloc这样的函数,则会在堆上分配内存槽。因此,如果我们将上面的行[3]更改为类似

的内容
int * p = malloc(sizeof(int));  // [3]

当你离开函数时,堆栈上分配的内存将被释放,但堆上分配的内存将保持分配状态,并且仍可访问,直到你释放它为止。图形化:

                                                  HEAP     Address Free (y/n)
                                               +---------+ 
                                               |         | 0xb4  - Yes
                                               |         | 0xb3  - Yes
                                               +---------+
       Context   STACK    Address             
 [3]          +---------+                      +---------+ 
=====>        | 0xb4    | 0xa3 <-- p           |         | 0xb4  - No
       func   | 3       | 0xa2 <-- x           |         | 0xb3  - Yes
              +---------+                      +---------+
              |         | 0xa1
       main   |         | 0xa0
              +---------+

 [4]          +---------+                      +---------+ 
=====>        |         | 0xa1                 |         | 0xb4  - No !!! Leak !!!
       main   |         | 0xa0                 |         | 0xb3  - Yes
              +---------+                      +---------+

正如您所看到的,在您离开函数后,由于没有指向动态分配内存的指针,因此会出现内存泄漏。避免这种情况的一种方法是返回指针(以便将新内存插槽的地址传递给调用函数)或将其存储在某处以便以后释放它。也可以在调用函数之前分配内存并将其作为参数传递给函数。这实际上取决于你的申请。