我编写了一个程序,它分配内存,并计算最低和最高指针的地址之间的大小。 我对结果感到惊讶。当我启动时,它需要20mb的内存,40,60 ... 200,220,240,... 3000mb,3020mb,然后突然爆炸,262000 mb,依此类推。 有人可以解释一下原因吗?
#include <iostream>
using namespace std;
int aaa;
int *max1=&aaa;
int *min1=&aaa;
void results(){
cout<<"min "<<min1<<endl;
cout<<"max "<<max1<<endl;
double mln= 1e6;
cout<<"min-max= "<<(max1-min1)/(1024*1024)<<"mb"<<endl;
}
void logic(int *c){
if(c>max1){
max1=c;
}
if(c<min1){
min1=c;
}
static int i;
i++;
if(i%800==0)
results();
}
int main(){
int *x;
int l=0;
while(l<=500000000){
l++;
x=new int[20000];
logic(&x[19999]);
}
}
答案 0 :(得分:4)
比较(并因此减去)未指向同一数组元素的指针是没有意义的(双关语)。
您在不相关的地址上执行指针运算,结果有什么意义?
您没有将最低地址与分配的同一块中的最高地址进行比较,而是将所见的最低地址与800个不同内存分配中看到的最高地址进行比较。
考虑所有这些调用之间发生的所有堆碎片(以及可能的回收)。你可以得到正面,负面或零作为你的差异。
如果您尝试确定的是堆的范围,那么这种方法过于随机,因为您无法保证在内存耗尽和崩溃之前找到最小和最大的地址。 / p>
还要考虑虚拟内存和分页的影响。通过虚拟内存的现代实现,您理论上可以访问您的进程可以解决的内存(我认为),无论RAM(您实际安装了多少内存)。
另见: Allocating more memory than there exists using malloc以及有关虚拟内存的评论中的链接。
答案 1 :(得分:0)
您的程序正在使用malloc()分配内存。这从进程堆中获取内存。堆由一个或多个连续范围的预留内存组成。无论何时从堆中分配,系统都将使用和操作堆数据结构,为堆内部提供所需大小的自由范围,并根据需要为此范围分配物理内存页。分配大量内存时,最终会消耗堆范围内的所有空间。然后系统将保留一个新范围。但是新范围将不会在旧范围之上,因为虚拟地址空间可以被分段,并且还存在ASLR(地址空间布局随机化),这导致系统使用随机基地址而不是遵循一致的算法。保留堆内存。所以你甚至不能指望你的程序的一致行为。