编译器可以优化内存管理在堆上分配静态数组吗?

时间:2011-07-27 15:43:11

标签: c++ windows static memory-management

我想在数据段中分配一个大字符数组,所以我使用了类似这样的代码:

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最初是在硬盘驱动器上分配的,直到第一次使用?

4 个答案:

答案 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程序。