C ++ / g ++:在这种情况下,编译器如何处理内存分配?

时间:2019-03-04 13:28:52

标签: c++ memory g++ heap-memory

由于代码的差异,g ++处理这种情况的方式是否有所不同?对于初学者来说,代码似乎完全相同。

我应该提到的是,两棵树都很大,每棵都包含大约十个张量,每个张量估计为10 ^ 5左右的整数。

编辑:所有数字都分配给堆,只有来自树根的一个指针实际上位于堆栈上。

{
        std::cout << "\nTrial #" << i << std::endl;
        v = createV(10, 5, 10);    

        ExTree<int> treeOpt = build_opt(v);
        {
            //...
            treeOpt.evaluate();
        }
        ExTree<int> treeNai = build_naive(v);
        {
            //...
            treeNai.evaluate();
        }
}

{
        std::cout << "\nTrial #" << i << std::endl;
        v = createV(10, 5, 10);    
        ExTree<int> treeNai = build_naive(v);
        ExTree<int> treeOpt = build_opt(v);
        {
            //...
            treeOpt.evaluate();
        }
        {
            //...
            treeNai.evaluate();
        }
}

我问这个问题,因为它似乎确实有所作为,我想知道为什么?或者,更确切地说,编译器是否意识到,treeOpt将不会在评估并释放到内存后再次使用?第二段代码导致std::bad_alloc频繁发生。

1 个答案:

答案 0 :(得分:1)

如果第一个块碰巧改变了v,确实会有所不同:

  • 第一个版本:ExTree<int>是基于经过修改的v构建的:

    {
        //...
        treeOpt.evaluate();
    }
    ExTree<int> treeNai = build_naive(v);
    
  • 第二个版本:ExTree<int>是基于原始的v

    ExTree<int> treeOpt = build_opt(v);
    {
        //...
        treeOpt.evaluate();
    }
    

如果未触及v,而您的程序是const-correct,则编译器仍然可以自由地重新排序。