首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这种使用alloca()有效吗?

这种使用alloca()有效吗?
EN

Stack Overflow用户
提问于 2014-06-06 12:38:24
回答 2查看 751关注 0票数 0

在使用std向量为我的国际象棋引擎保存移动列表后,我意识到,由于国际象棋的平均因数为35 (大约从一个典型位置移动到35次合法移动),该向量正在调整大小,从而对移动生成器的性能产生负面影响。解决这个问题的一种方法(我今天才意识到)是为向量保留最小容量。然而,使用alloca()的可能性引起了我的注意。这可能是一个非常简单的问题,但是关于alloca()的文档非常稀少,很少有如何使用它的例子。

因此,Allocation of variable-sized class的答复提到不能调整堆栈分配的大小。然而,以下内容是否有效?

代码语言:javascript
复制
    struct MoveList
    {
       MoveList(): capacity(10)
       {
          moves = (Move*) alloca(sizeof(Move) * 10);
       }
       void resize()
       {
          capacity *= 2;
          moves = (Move*) alloca(sizeof(Move) * capacity );
       }
       void push_back();
       Move* moves;
       int size;
       int capacity;
    }

具体来说,如果第一次从alloca()获得10的容量是不够的,那么再次调用alloca()来分配更多内存是否在语法上是有效的(并且是正确的)?这种方法会提供更好的性能(与保留()的std向量相比),还是只会增加堆栈溢出的可能性?我的移动结构需要大约28字节的内存,我怀疑引擎会递归地搜索(使用alpha-beta)到可能最大的7或8层,这样可能会从堆栈中使用大约28 * 35 *8~ 8kb的最大值。我在某个地方读到,典型的堆栈有1Mb的限制,所以这不应该太多,对吗?

编辑:感谢下面的答案,我现在意识到我对alloca()所做的事情的最初理解是错误的。但是,我仍然想知道是否可以以以下方式使用alloca():

代码语言:javascript
复制
    int main()
    {
        int* arr = (int) alloca(sizeof(int));
        arr = alloca(sizeof(int) * 2 ));//is this 'resizing' valid?
    }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-06 12:44:54

函数alloca在堆栈上分配内存,一旦调用alloca的函数返回,内存就不再可用。这意味着,一旦MoveList构造函数或resize函数返回,内存就不再可用。您认为可以在MoveList对象的生命周期内使用此内存的假设是错误的。

对您来说最好的选择是使用std::vector和预订。

票数 3
EN

Stack Overflow用户

发布于 2014-06-06 12:53:12

您似乎不明白非标准的alloca()表达式实际上是做什么的。它在调用函数的堆栈帧中分配内存。在您的示例中,这意味着分配给moves成员的空间的生存期是构造函数的生存期:

代码语言:javascript
复制
   MoveList(): capacity(10)
   {
      moves = (Move*) alloca(sizeof(Move) * 10);
      ... moves is valid from this point

      // "moves" stops being valid at this point
   }

因为其余的构造函数是空的,所以这是而不是。(此外,alloca()还有一个副作用,即防止调用函数内联--另一个意外的副作用。)换句话说,为了回答标题中的问题,alloca()的这种用法是无效的

即使它在某种程度上是有效的,因为alloca()没有相应的对象来调整或释放分配的内存(由于它的工作方式,它也不能有一个内存),对于任何需要调整区域大小的情况,这都是非常不合适的--这正是您试图使用它的方式。

std::vector的调整容量通常已经成为指数增长的因素,因此添加您自己的能力是不必要的。如果你不确定,衡量性能,看看什么对你有用。对于您的情况,只需调用std::vector<T>::reserve()就可以确保向量以乐观的大小开始,从而消除了重新分配的需要。或者使用std::deque,它从不重新分配元素(代价是访问速度稍慢)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24082061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档