简体   繁体   English

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

[英]How can I free a struct pointer that i need

I am trying to avoid memory leaks in my code. 我试图避免代码中的内存泄漏。 I need to de-allocate pElement, line and pSecond, without losing the values inside pImage. 我需要取消分配pElement,line和pSecond,而不会丢失pImage内部的值。 Because I need to print those values inside my print function. 因为我需要在我的打印函数中打印这些值。

My add function contains struct GraphicElement *pElements;, struct GraphicElement *pSecond;, struct Point point;. 我的添加函数包含struct GraphicElement * pElements ;、 struct GraphicElement * pSecond ;、 struct Point point;。

I allocate memory using malloc for each struct and then add the values and then I pass the final values into pImage. 我使用malloc为每个结构分配内存,然后添加值,然后将最终值传递到pImage中。 All my other functions work perfectly besides the fact that I always end up with 3 memory leaks. 我所有的其他功能都可以正常工作,除了我总是会发生3次内存泄漏。 Because I didnt not free(pSecond);....free(pElement)...free(line); 因为我没有free(pSecond); .... free(pElement)... free(line);

If I try to free them before my function exits and after passing the values into pImage. 如果我尝试在函数退出之前以及将值传递到pImage之后释放它们。 My values all get erased. 我的价值观都被抹去了。

How can I free those values inside my add function locally? 如何在本地的add函数中释放这些值?

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

How can I free those values inside my add function locally? 如何在本地的add函数中释放这些值?

It is not possible to explicitly free a memory allocated locally. 无法显式释放本地分配的内存。 Nor to locally free some memory. 也不要在本地释放一些内存。 Once freed, a memory slot cannot be accessed and the data stored inside are lost. 一旦释放,将无法访问内存插槽,并且内部存储的数据将丢失。

In C, you have two option to allocate some memory: you can allocate it on the heap or on the stack. 在C语言中,有两种方法可以分配一些内存:您可以在堆或堆栈上分配它。 The memory slots reserved on the heap can be accessed globally and will remain until they are explicitly freed. 堆上保留的内存插槽可以全局访问,并且将一直保留直到明确释放它们为止。 The one reserved on the stack are only valid while you stay within the context they were created. 堆栈中保留的那个仅在您处于创建它们的上下文中时才有效。

Let's say you execute the following code : 假设您执行以下代码:

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

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

  // [4]
  return 0;
}

The instruction [2] will allocate some memory on the stack. 指令[2]将在堆栈上分配一些内存。 The second one ( [3] ) will do the same and will store the address of the of the first variable in the new memory slot. 第二个变量[3] )将执行相同的操作,并将第一个变量的地址存储在新的内存插槽中。 After the function returns ( [4] ), this memory is freed. 函数返回( [4] )后,将释放该内存。 Graphically, here is what happens : 以图形方式,这是发生的情况:

       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
              +---------+

So if i use malloc inside a function. 因此,如果我在函数内使用malloc。 Once I exist the function the allocated memory on the heap is freed automatically? 一旦存在该函数,堆上分配的内存会自动释放吗?

It's the opposite. 相反。 If you use, a function like malloc , the memory slot will be allocated on the heap. 如果使用像malloc这样的malloc ,则会在堆上分配内存插槽。 So if we change the line [3] above to something like 因此,如果我们将上面的[3]行更改为类似

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

The memory allocated on the stack will be freed as you'll leave the function, but the memory allocated on the heap will remain allocated and will still be accessible, until you free it. 离开函数时,将释放在堆栈上分配的内存,但在堆上分配的内存将保持分配状态,并且仍然可以访问,直到您释放它为止。 Graphically : 图形方式:

                                                  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
              +---------+                      +---------+

As you can see, after you leave the function, you have a memory leak as you don't have any pointer to the dynamically allocated memory. 如您所见,离开函数后,由于没有指向动态分配内存的指针,因此内存泄漏。 One way to avoid this is to return the pointer (so to pass the address of the new memory slot to the calling function) or to store it somewhere to free it later. 避免这种情况的一种方法是返回指针(以便将新内存插槽的地址传递给调用函数)或将其存储在某个地方以供以后释放。 It's also possible to allocate the memory before calling the function and to pass it to the function as a parameter. 也可以在调用函数之前分配内存,并将其作为参数传递给函数。 It really depends on your application. 这实际上取决于您的应用程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM