【问题标题】:changing pointer of a dynamically allocated array更改动态分配数组的指针
【发布时间】:2017-08-10 14:20:17
【问题描述】:

当我们像这样动态声明一些东西时

int *ptr = new int [100];

然后改变指针地址(即指向别的东西)

int pointer[5] = {1,2,1,3,1,};
ptr = pointer ; 

现在包含 100 个整数的内存会发生什么?

有没有办法重新控制那段记忆?如果没有,是否会导致内存泄漏?

【问题讨论】:

    标签: c++ pointers memory-leaks dynamic-allocation


    【解决方案1】:

    现在包含 100 个整数的内存会发生什么?

    它被“泄露”了,因为你丢失了唯一的句柄。

    有没有办法重新控制那段记忆?

    不,除非您在重新分配 ptr 之前注意创建另一个句柄。

    int* ptr = new int[100];
    int* ptr2 = ptr;
    ...
    ptr = pointer;
    delete [] ptr2;
    

    在实际代码中,您不会依赖指向已分配内存的原始指针,而是使用最适合您的问题的 RAII 类型(例如std::vectorstd::unique_ptr 等)

    【讨论】:

    • 并且操作系统会检测到这个内存泄漏并在程序终止后释放它。对吗?
    • @RazaUsman_k 对于常用的操作系统是的。但它仍然应该被认为是一个错误。另请注意,对于用户定义的类型,不运行析构函数可能会导致异常。
    • @juanchopanza 关于这个主题有什么好的参考资料/阅读资料可以进一步澄清吗?
    【解决方案2】:

    在您提供的示例中,ptr 是唯一一个引用由new int [100] 创建的一百个int 的指针(即指向第一个元素)。

    更改ptr 的值不会影响一百个int。这意味着ptr 不再包含第一个元素的地址。

    实际上,在分配ptr = pointer 之后,分配的内存被称为泄漏 - 它已被分配,在标准 C++ 中无法访问它,在标准 C++ 中也无法释放它(例如,使它消耗的内存可用于在另一个 new 表达式中重新分配)。

    在您的情况下保持对内存的控制的唯一方法是将ptr 的值存储在另一个变量(或结构的成员,或指针数组的元素......)之前重新分配它。如果在重新赋值ptr之前已经存储了ptr的值,并且存储的地方仍然存在,则可以取回该值。

    实际上,最好使用标准容器(例如std::vector<int>)而不是在代码中使用新表达式。这样,只要容器存在,就可以访问容器的内容(就您的程序而言,当容器存在时,就不再存在了)。

    【讨论】:

      【解决方案3】:

      使用new 分配的任何内存块在被相应的delete 释放或分配内存的进程终止之前都是不可用的。

      内存分配器实际上不知道您在分配的对象上维护哪些引用。如果您设法提供有效地址,它只允许您释放相应的内存块。
      如何跟踪这些地址完全取决于您。

      因此,如果由于某种原因您丢失了一块内存(通过覆盖示例中的数据指针,或者只是忘记在某个时候使用它来释放内存),您将剥夺您的系统这一位内存,直到底层进程终止。

      如果“内存失效”是无意的,这将成为内存泄漏,如果这种情况反复发生,则更是如此。

      例如,如果您需要一些与进程具有相同生命周期的数据,您可以进行一次性分配并且永远不要释放内存(因为它会在终止时自动释放)。这可能会吓坏良好实践的狂热分子,但仍不能算作内存泄漏。

      另一方面,还有其他方法可以弄乱内存分配器:将无效指针传递给delete(包括对已释放对象的引用,即多次删除对象的同一实例,或指向不是由new 分配的东西的指针,例如局部或全局变量)将为您带来未定义行为的美妙领域,这可能导致随机内存丢失、数据损坏或核崩溃。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-16
        • 2013-05-26
        • 2020-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多