我想在数据段中分配一个大字符数组,所以我使用了类似这样的代码:
const int size = 1000000000 ;
static char chr [ size ] ;
int main ( )
{
chr [ size - 1 ] = 1 ; // line 1
string s ;
cin >> s ; // line 2
}
第1行:我把这行放在一起,这样数组至少使用一次而且没有从编译器中优化出来
第2行:为了停止执行并检查内存占用,例如:在windows的任务管理器中
在Windows系统上,结果是当程序卡在第2行等待用户的输入时,在任务管理器上(在内存和工作集的两列中),进程使用的内存量小于预期的1GB。
然后我尝试使用以下代码:
int main ( )
{
for ( int i = 0 ; i < size ; ++ i )
{
chr [ i ] = i ;
}
string s ;
cin >> s ; // line 2
}
现在,当程序到达第2行时,内存使用量会在快速增长几秒后达到预期的1GB。
似乎内存是动态分配而不是静态分配。
我对阵列/内存模型的理解是错误的吗?
编译器是否动态分配大量数据以进行优化?
任务管理器是否显示物理分配的内存,因此1GB最初是在硬盘驱动器上分配的,直到第一次使用?
答案 0 :(得分:2)
操作系统仅在访问后才分配内存。阅读有关请求分页的信息。
答案 1 :(得分:0)
您正在分配虚拟内存。
如果您实际上没有使用它,则无需存储在任何地方。
答案 2 :(得分:0)
由于您实际上并未使用该阵列(删除它不会产生影响 在程序的输出上,编译器可以自由地优化它。 并且一些系统执行一种惰性分配形式:它们不分配(和 在您实际访问之前,为各个页面收取费用 他们;即使没有优化,您也只需触摸一页。 (可以说,你不能在一个上有一个符合C或C ++的实现 做懒惰分配的系统。但是既然Windows和Linux都是 有罪,我们必须忍受它。)
答案 3 :(得分:-1)
编译器是否动态分配大量数据以进行优化?
不,它没有!
编译器永远不会做那样的优化。
只有显式动态分配的内存才能进入freestore(或堆)
当你这样做时
const int size = 1000000000 ;
static char chr [ size ] ;
在全局范围内,使用的内存甚至不是堆栈内存,使用的内存是数据段或BSS段但是,C ++标准没有指定应该分配的位置,它保留为编译器的内部实现,但它绝对没有在freestore(aka heap)上分配
另外,不要使用任务管理器来分析C ++程序的内存使用情况,特别是使用分析工具来执行此操作,任务管理器向您显示的不是w.r.t程序。