堆上的内存地址是否可以重用?

时间:2012-06-22 17:59:41

标签: c++ memory

标题问题的进一步解释是有序的,让我解释一下我的情景。

我有一个列表容器,指向堆上的多个对象。无论何时创建新对象,都会将指向它的指针添加到列表中,并且每当删除对象时,其指针都将被删除。可以肯定地说,此列表上的所有指针始终有效。

列表中的许多对象都包含指向同一列表中其他对象的指针。

在我取消引用任何指针之前,我想使用CheckAgainstList(ptr*)函数来确保一个对象指向同一列表中的另一个对象,因此不指向此后的对象删除。

现在就拿你的锡箔帽,这可能吗?

  1. 对象A有一个指向对象B的指针,其内存地址为 0x00988e50
  2. 对象B已删除。
  3. 创建对象C并将其放入新释放的内存空间0x00988e50中。
  4. 当我们检查指针时,
  5. CheckAgainstList(ptr*)返回true,因为对象C在列表中并且与用于占用的内存地址B相同。
  6. 现在我们有一个错误,因为A认为它有一个指向B的指针,但是B已经消失,而C已取而代之。

    这个潜在的错误甚至可能吗?

5 个答案:

答案 0 :(得分:6)

不仅可能,而且非常可能。一个好的内存分配器会尝试尽可能多地重用内存,以减少碎片和膨胀。

您尝试解决的问题可能适用于weak_ptr,可以在使用之前检查其有效性。

答案 1 :(得分:4)

是的,错误是完全可能的。

基本上你正在做的事情非常危险,很快就会导致错误。您可能最好使用某种类型的引用计数智能ptr。 C ++ 11包含std :: shared_ptr,这意味着您可以使用代替普通指针。这样,在所有内容都完成后,内存将不会被释放,并且可以减轻您描述的问题。

你唯一的另一个选择就是扫描所有其他对象,看看他们是否引用了已删除的'B',并在指向现在已删除的指针时执行类似“null”的操作。

答案 2 :(得分:4)

内存地址确实可以重复使用 - 具体取决于操作系统。否则,如果一个程序进行了大量的分配和解除分配,超过了机器中的RAM,它将无法继续。

最后,答案更多的是关于操作系统及其内存管理方案,而不是C ++本身。毕竟,在分配免费存储(动态)内存时,最原始的是,进程(通过标准库函数)调用特定的OS例程来分配请求的内存量并将地址返回到分配的内存。 / p>

答案 3 :(得分:1)

如果您只创建一种类型的对象,则更有可能出现此错误。但它总是完全可能的。

答案 4 :(得分:0)

是的,这可能发生。为了防止这种情况,当您删除对象时,请浏览列表并将指向已删除对象的任何指针设置为NULL。