有没有办法获得堆上可用的内存地址范围?

时间:2011-08-09 05:52:31

标签: c++ memory new-operator

在我看来,这就是内存在C ++中的工作方式:

如果您使用new,那么您要求编译器的实现从堆中提供一些内存(任何内存)。

如果你使用了放置新语法,那么你要求重新分配一个你已经知道地址的特定内存位置(让我们假设它也来自堆),这可能也是最初从{ {1}}运营商在某个时候。

我的问题是:

无论如何都知道程序可以使用哪些内存位置先验(即没有从new运算符已经提供给您的堆中重新分配内存) ?

堆中的内存是否连续?如果是这样,你能找到它的起始位置和结束位置吗?

P.S。试着尽可能快地尽可能接近金属......

4 个答案:

答案 0 :(得分:5)

不以任何便携方式。现代操作系统倾向于使用分页(也称为虚拟内存),因此可用内存量不是一个容易回答的问题。

如果你需要编写自己的堆,那么堆中的内存不需要是连续的,这不是很难做到的。

答案 1 :(得分:2)

程序“先验”可用的内存包含您定义的变量。编译器已准确计算出程序需要多少。没有什么“额外”你可以用来做别的事。

您需要动态创建的新对象是从免费存储(也称为堆)中分配的,可能是使用new,但更常见的是使用库中的容器,如std::vector

语言标准没有详细说明它是如何工作的,只是如何使用它。

答案 2 :(得分:1)

这是一个非常困难的问题。在现代操作系统中,存在诸如存储器管理器的子系统。当您的程序执行new运算符时,有两个选项:

  • 如果有足够的内存可用于编程,则会在程序的堆中获得指向内存的指针
  • 如果没有足够的内存,则执行操作系统的内存管理器并确定要执行的操作:为程序提供更多内存(假设它会调整堆的大小)或拒绝并抛出异常。< / LI>
  

无论如何都要先知道程序可以使用哪些内存位置(即没有从新运算符已经给你的堆中重新分配内存)?

我想强调它取决于操作系统的版本和环境。

  

堆中的内存是否连续?

不,它可能是非连续的。

答案 3 :(得分:1)

未定义从newmalloc()的连续调用中收到的地址的连续性。 C运行时和操作系统可以在连续new的地址空间中自由地返回指针。 (事实上​​,它可能会这样做,因为好的分配器会根据分配的大小从不同的池中提取以减少碎片,并且这些池将位于不同的页面中。)

但是,new中的 分配中的字节保证是连续的,所以如果你这样做

int *foo = new int[1024 * 1024] 

你会得到一百万个连续的单词。

如果你真的需要一个大的连续分配,你可能需要使用特定于操作系统的函数来执行此操作(除非有人隐藏了一些我不知道的Boost库)。在Windows上,VirtualAlloc()。在POSIX上,mmap()