2010-12-04 39 views
1

我试图找到一些明确解释的教程,在释放内存时需要记住的事情是什么。但是我找不到这样的东西。任何人都可以让我知道程序员在处理C中的内存时应该记住什么是主要的东西。我目前正在处理链接列表。有些情况下,新链接列表创建使用2个或多个现有链接list.For例如:在C中释放内存时应该考虑的主要事情是什么?

list l1; 
list l2 
list l3 = list_append(l1,l2) 
list l4 = list_append(l3,l1) 
list l5 = list_append(l3,l4) 

什么是释放,我要跟着解除分配内存的序列?

此处list_append是返回列表副本的函数。

+2

不知道'list_append'是干什么的。它是复制输入列表,还是将它们链接在一起? – 2010-12-04 17:29:17

+0

@Steve the list append copy the input lists。 – thetna 2010-12-04 17:32:53

回答

3

当使用malloc/free函数族时,有两条规则需要遵守。

  1. 您可以通过一个malloc家庭分配器仅free有效的记忆回来了,释放它使之无效(所以双释放是一个错误的释放不通过malloc获得的内存)。
  2. 在释放内存后访问内存是错误的。

这里是重要的部分:分配器提供没有设施,以帮助您遵守这些规则

你必须自己管理它。这意味着您必须安排程序的逻辑以确保始终遵守这些规则。这是c并且巨大的乏味和复杂的责任倾倒在你的肩膀上。

让我提出两个模式是比较安全的:

分配和释放在同样的情况下

//... 
{ 
    SomeData *p = malloc(sizeof SomeData); 
    if (!p) { /* handle failure to allocate */ } 
    // Initialize p 

    // use p various ways 

    // free any blocks allocated and assigned to members of p 
    free p; 
} 
//... 

在这里,你知道数据p指向被分配一次,并释放一次,并且只使用在之间。如果SomeData的内容的初始化和释放是不平凡的,你应该包起来的一对夫妇的功能,使得这降低了

//... 
{ 
    SomeData *p = NewSomeData(i,f,"name"/*,...*/); // this handles initialization 
    if (!p) { /* handle failure to allocate */ } 

    // use p various ways 


    ReleaseSomeData(p) // this handles freeing any blocks 
        // allocated and assigned to members of p 
} 
//... 

称它是“范围所有权”。您会注意到它与本地自动变量没有多大区别,并且只提供了几个选项,这些选项对于自动变量而言不可用。

呼叫第二个选项“结构所有权”:删除分配的内存块这里的责任是交给一个更大的结构:

List L = NewList(); 
//... 

while (something) { 
    // ... 
    Node n= NewNode(nodename); 
    if (!n) { /* handle failure to allocate */ } 
    ListAdd(L,n);    // <=== Here the list takes ownership of the 
           // node and you should only access the node 
           // through the list. 
    n = NULL; // This is not a memory leak because L knows where the new block is, and 
      // deleting the knowledge outside of L prevents you from breaking the 
      // "access only through the structure" constraint. 
    //... 
} 

// Later 
RemoveListNode(L,key); // <== This routine manages the deletion of one node 
         // found using key. This is why keeping a separate copy 
         // of n to access the node would have been bad (because 
         // your separate copy won't get notified that the block 
         // no longer valid). 

// much later 
ReleaseList(L); // <== Takes care of deleting all remaining nodes 

鉴于你有节点列表,添加和删除,你可能考虑结构所有权模式,所以请记住:一旦你给予该结构的结构,你只需就可以通过该结构来访问它。

1

第一个原则是:

不管你分配(用calloc/ malloc的),你需要释放,最终。如果名单深在每个复制

在你追加的情况下,我看不出有什么问题。你需要分开释放每个列表。

2

一般的问题意义不大,唯一合理的答案似乎很明显:

  1. 那记忆被一审动态分配
  2. ,继释放您不要尝试使用内存再次
  3. 你至少要维护一个指向分配的指针,直到你需要释放它(即不要让你对该块的唯一引用超出范围或被销毁)。

第二个要求可以通过在释放后将指针设置为NULL或零来辅助,但指针可能在其他地方被保持,但它不是简单的。

第三个要求尤其是复杂数据结构中的问题,其中分配的内存可能包含本身包含指向已分配内存的指针的结构。在取消分配更高级别的结构之前,您当然需要释放这些资源。

2

任何人都可以让我知道什么是 主要事情是一个程序员 应该记住,而deallocting C中的内存

的基本原则是非常简单的:任何内存使用分配包括malloc,callocrealloc的* alloc函数系列必须通过相应的free()调用重新分配。

当传递指针(内存地址)free(),记住的只有有效存储器地址可以传递给free()是以前由的* ALLOC函数返回一个内存地址。一旦内存地址传递给free(),该内存地址不再有效,不能用于任何其他目的。

0

使用valgrind(1)向您展示在您的特定情况下终止时仍存在哪些对象,然后修改您的代码以确保释放不必要的对象。

0

那么最好的答案是一个问题..为什么你是用C编写代码,而不是使用更高级别的语言和更好的内存管理?

相关问题