C ++ - 使用“new”在堆上分配内存

时间:2011-01-29 09:26:39

标签: c++ heap new-operator dynamic-memory-allocation memory-address

如果我有以下声明:

int *x = new int;

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

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

delete x;

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

之后说我再次做了以下事情:

int *x = new int;

x是否会指向它在删除之前在堆中指向的相同旧内存地址?

如果我在delete

之前做了这件事,该怎么办?

x = NULL;

然后,这样做了:

int *x = new int;

x是否会指向堆其他上的内存地址而不是旧内存地址?

感谢。

6 个答案:

答案 0 :(得分:10)

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

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

答案 1 :(得分:2)

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

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

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

在删除前执行此操作:

x = NULL;

然后是内存泄漏。你失去了什么都没有的记忆,而你因为失去了它的地址而无法自由。 (你可以删除一个空指针,它什么都不做)

这样做太多时间会导致系统崩溃/减速更多,因为所有内存都被浪费了。 (使用磁盘上的交换太多等等......)

不要期望在删除后获得相同的新地址,然后重新获得新地址。虽然它可能会不时发生,随机发生。

答案 5 :(得分:1)

1)释放后,如果再次使用相同的变量进行分配,则无法保证您将获得相同的内存块。考虑一下如何实现新功能,即使使用自定义分配器,也可以通过任何方式实现。此外,其他线程可能在free()和new()调用之间使用new,并“偷走”你的内存

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