7

如果我有以下陈述:

int *x = new int;

在这种情况下,我在堆上动态分配了内存。换句话说,我现在有了一个对象的reserved内存地址int

在那之后说我做了以下事情:

delete x;

这意味着我freed up在堆上的内存地址。

说之后我又做了以下事情:

int *x = new int;

x指向它在被删除之前指向堆的同一个旧内存地址吗?

如果我以前这样做会怎样delete

x = NULL;

然后这样做:

int *x = new int;

x指向堆上的内存地址而不是旧地址吗?

谢谢。

4

6 回答 6

11

在第一种情况下,您可能会再次获得相同的内存块,但不确定。

在第二种情况下,由于您尚未释放内存,因此几乎可以肯定您将在不同的地址获得不同的内存块。有 C++ 的垃圾收集器。如果您使用其中之一,可以想象垃圾收集器将在您将指针清空(因此您不再有权访问先前分配的内存块)和再次请求分配之间运行。在这种情况下,您可以再次获得相同的内存块。当然,如果没有垃圾收集器,你只是在泄漏内存,所以无论如何你都不能这样做。

于 2011-01-29T09:32:50.930 回答
3

您要问的是完全未定义的(根据 C/C++ 标准),并且取决于实现。

您应该很容易使用您的编译器版本进行测试。

不过,您应该注意的是永远不要依赖这种行为的结果,因为它可以随时更改/使用任何操作系统/甚至升级到您的编译器。

至于我认为可能发生的事情,你最有可能得到相同的地址,除非你的程序中有其他线程也在同一时间分配。但是即使那样,如果您的编译器的特定 malloc 实现决定为不同的线程使用不同的堆(这在性能方面更好),您可能会得到相同的地址

于 2011-01-29T09:33:06.743 回答
2

当您在删除之前执行此操作时:

x = NULL;

然后是内存泄漏。您丢失了无用的内存,并且您无法释放内存,因为您丢失了它的地址。(你可以删除一个空指针,它什么也不做)

这样做太多时间可能会导致系统崩溃/减慢速度超过可接受的程度,因为您的所有内存都被浪费了。(在磁盘上使用太多交换等等......等等......)

不要指望在删除后得到完全相同的新地址,然后又是一个新地址。虽然它可能不时发生,随机发生。

于 2011-01-29T09:31:56.360 回答
1

不,没有这样的保证。这完全取决于用于满足您的内存请求的分配器。但是,C++ 是强大的野兽,让我们覆盖 new 运算符。您可以构建一个自定义分配器(内存管理),以某种方式提供内存,这有时非常有用。

于 2011-01-29T09:28:59.817 回答
1

不,从 second 返回的指针new int;可以指向有效可写地址范围内的任何位置。不能保证之前释放的区域会被使用(实际上大多数时候它可能不会被使用,因为堆管理器可能会选择在稍后的某个时间点释放实际内存)。

于 2011-01-29T09:31:46.557 回答
1

1)释放后,如果您再次使用相同的变量进行分配,则无法保证您将获得相同的内存块。想想 new 是如何实现的,它可以以任何你能想象的方式完成,甚至使用自定义分配器。此外,其他线程可能在 free() 和 new() 调用之间使用 new 并“偷走”你的内存

2)不要这样做。您正在失去参考,如果您在 NULL 指针上应用 delete 运算符,它将什么也不做。因此,如果您不将引用存储在其他变量上,您可能会发生资源泄漏。如果您再次调用 new ,它肯定会在其他地方分配,假设没有人释放第一个 new() 授予的区域

于 2011-01-29T09:32:49.473 回答