【问题标题】:Why do pointers cause memory leak to dynamically allocated integer?为什么指针会导致内存泄漏到动态分配的整数?
【发布时间】:2012-12-23 23:46:15
【问题描述】:

“因为 pnValue 是唯一保存动态分配的整数地址的变量,所以当 pnValue 被销毁时,就不会再引用动态分配的内存了。这称为内存泄漏。结果,动态分配的整数无法删除,因此无法重新分配或重用。” {quoted from LearnCpp.}

为什么 pnValue 会保存动态分配的整数的地址? 如果指针只是指向地址,为什么销毁指针会影响地址? 这是否意味着在动态分配的整数中,我们必须始终拥有指针,因为指针以某种方式地址?

【问题讨论】:

    标签: c++ pointers memory memory-leaks


    【解决方案1】:

    所有已定义的对象都存在于内存中并具有地址。对象的地址是对象开始驻留的内存位置。所以在一维内存空间中,如果一个对象开始驻留在插槽 100,那么 100 就是该对象的地址。

     99 100 101  102  103  104  105  106
    =====================================
       | O  | B  | J  | E  | C  | T  |    
    =====================================
         ^
         |
         |
     pnObject
    

    指针是包含其他对象地址的对象。动态创建对象时,它是在堆内存中创建的,没有作用域。只要您不明确删除分配的内存或分配内存的程序死亡,它就会继续存在。

    内存是通过 c 库函数 mallocc++ 运算符 new 动态分配的,它返回地址,即对象开始驻留的堆内存中的起始位置。您应该将地址保存在一个变量(称为指针的特定类型)中,该变量现在保存对象的地址。

    Object *pnValue = new Object();
    

    只要您知道堆中新创建对象的地址,您就可以控制,但如果您忘记了地址,无论是通过销毁指针变量、覆盖内容还是根本不存储地址,您都无法访问该位置并且以后无法释放/删除分配的内存。

     99 100 101  102  103  104  105  106
    =====================================
       | O  | B  | J  | E  | C  | T  |    
    =====================================
    

    【讨论】:

      【解决方案2】:

      指针“只指向地址”。这就是说,如果您删除所有指向该地址的指针,则无法“访问”存储在那里的内存以删除/释放它。一旦没有指针“指向”该位置,您就无法再清理该内存,因此您会发生泄漏。

      销毁指针不会造成泄漏 - 如果有另一个指针可用于访问内存以清理它。如果没有保留其他指针,则销毁指针只会删除访问该内存的能力。

      【讨论】:

      • 我认为指针是“可选的”:我们没有来制作指针。
      • @Raindrop 从某种意义上说,您可以选择将数据存储在堆栈上。然而,堆栈的大小是有限的。此外,任何集合(listmap 等)都会分配内存来存储它们的项目,但它们会对用户隐藏它。
      • Î 想知道 delete[] 实际是如何工作的?假设我们有一个“new unsigned char[100];”,然后在上面调用 delete[]。应用程序如何知道这 100 个字节现在又空闲了?或者更确切地说,它是如何存储它必须释放的 100 个字节的。
      • @AntonRoth:这是一个单独的问题,但简而言之,几乎所有实现都将分配内存的大小存储在分配内存之前的标头结构中。
      【解决方案3】:

      指针不指向地址,它们存储地址。据说它们“指向”对象。它们指向的对象是位于它们存储的地址中的对象。

      想想通讯录。每个条目都是指向您的一个朋友的指针(您的朋友是对象)。假设您的朋友遍布全国(您的计算机内存),而您的内存是垃圾。所以你需要你的通讯录来找到你的朋友。如果您丢失了地址簿的一页(指针被破坏),则地址在该页上的朋友将丢失给您。也就是说,除非你有一个备份副本(更多的指针持有相同的地址)。

      【讨论】:

        【解决方案4】:

        就像 Benjamin 说的,指针存储了你想要访问的数据的地址。 如果您创建一个指针,您还必须保留所需的内存量。否则,您可以轻松创建访问冲突。您还应该知道,内存泄漏不仅令人讨厌,因为您的应用程序的虚拟空间增加了,而且对指针的错误处理也是每个想要破坏您的应用程序或系统的人的一个很好的切入点。 为了查找内存泄漏,这里有一些项目@codeproject.com,如下所示: http://www.codeproject.com/Articles/9815/Visual-Leak-Detector-Enhanced-Memory-Leak-Detectio

        【讨论】:

          【解决方案5】:

          为什么 pnValue 会保存动态分配的整数的地址?如果指针只是指向地址,为什么销毁指针会影响地址?

          您对“地址”一词的两种不同用法感到困惑。这个词既可以用来指代如何定位一个地方的信息,也可以用来指代这个地方本身。考虑:

          1) 我已经把地址写在了一张纸上。

          2) 我现在开车去那个地址。

          使用第一种意义,指针存储地址;有关如何定位特定数据或内存的信息。使用另一种意义,指针指向一个地址。它们指向数据或内存的位置。就像你在一张纸上写下一个地址(到达某个地方的信息),那张纸现在指向地址(那个地方)。

          因此销毁指针会破坏有关如何访问该位置的信息。

          这是否意味着在动态分配的整数中,我们必须始终有指针,因为指针在某种程度上就是地址?

          当您使用new 分配内存时,您将获得有关如何访问已分配内存的信息。如果您最终未能将相同的信息返回给delete,就会发生泄漏。所以是的,您必须始终以某种方式维护该信息,以便最终将其返回给delete

          【讨论】:

            猜你喜欢
            • 2012-08-10
            • 1970-01-01
            • 1970-01-01
            • 2013-07-12
            • 1970-01-01
            • 2017-02-13
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多