当动态内存不超出范围时,为什么动态内存不会被清洁

Why does dynamic memory not get cleaned when it is out of scope

本文关键字:内存 动态 为什么 清洁 范围      更新时间:2023-10-16

我刚刚开始使用C (熟悉其他语言),我想知道一些事情。

例如,当创建一个动态大小的数组时,为什么在范围不超出范围时不会被删除,但是却不会删除固定尺寸的数组?

,例如,使用以下代码:

int foo()
{
    int baz[5]; // Gets removed out of scope
    int *bar = new int[5]; // Does not get removed, becomes a leak
}

由于BAZ和BAR都是通往数组开始的指针,因此"运行时环境"不能应用相同的技术(检测某物是否超出范围,并在此操作时将其删除)固定尺寸为动态尺寸?

它不能做这种事情有什么区别。

当动态内存不超出范围时,动态内存不会被清洁

因为动态内存的目的是是在范围末尾分配的。当您需要在一个范围中分配内存时,使用动态内存,然后在另一个范围内使用并将其分配给分配。

例如,当创建一个动态大小的数组时,为什么不将其删除

因为这是new的主要目的:允许您控制对象何时被破坏,这可能是其创建范围之外的。

(在其他情况下也需要动态分配 - 创建数组的大小或对象在编译时间不知道或可能对堆栈太大的对象 - 因为该语言没有直接提供单独的机制对于这些情况。在这种情况下,您可以使用智能指针或容器将对象的寿命绑定到范围。)

由于bazbar都是通往数组开始的指针

不,他们不是。baz是一个数组;当它脱离范围时,它被摧毁了。bar是一个数组的指针;它被摧毁了,但指出的数组不是。

"运行时环境"不能应用相同的技术

否。通常,没有办法知道指针是否指向动态对象。即使存在,也没有办法知道在该指针被销毁后是否还有其他参考文献。

,因为固定大小数组分配在函数的堆栈中,并且在程序的堆中分配了动态数组。功能堆栈是用于存储本地变量的内存空间。当达到功能端时,堆栈将自动免费。堆是不同的,一旦程序关闭,它是免费的。

动态内存不会在范围结束时自动交易,因为动态内存的目的是具有更多的控制。您可能需要在分配的同一范围的末尾进行处理,但是您可能需要在其他地方进行处理 - 这完全取决于您的程序的设计。

从范围中做的事情是一个指向记忆的指针,而不是内存本身(它没有范围,只是终身时间)。每当任何指针死亡时,您都不想自由记忆 - 几乎总是要分发临时指针(例如将它们传递给其他功能),从功能中返回指针,将指针的副本存储在其他地方等等

换句话说,在使用动态分配的内存过程中,您必须创建并销毁许多许多指数。您不希望大多数这些指针都带有内存,只能使用 last 指针来释放内存。任何早些时候,您都会得到悬空的指针;以后再有指针,再也无法释放指针。

将记忆操作搭配到指针寿命的方法,包括传输所有权的能力:返回指针,将其从一个变量移至另一个变量等。这是一个如此 - 称为智能指针,特别是unique_ptr

但是,这不适合指针类型,您仍然需要用于上述所有用途的非持有指针(分发出临时引用而无需释放内存)。此外,据我所知,这个想法(或至少其采用到主流中)早于C 。它肯定早于C,这意味着C 即使Bjarne天生就具有智能指针的硕士学位,也需要保留原始的指针。