【发布时间】:2023-03-18 21:12:01
【问题描述】:
在使用标准向量保存我的国际象棋引擎的移动列表后,我意识到因为国际象棋的平均因子为 35(即从典型位置开始的 35 次合法移动),向量的大小调整了很多,因此对移动生成器的性能产生负面影响。解决这个问题的一种方法(我今天才意识到)是为向量保留最小容量。然而,使用 alloca() 的可能性引起了我的注意。这可能是一个非常简单的问题,但是关于 alloca() 的文档非常少,关于如何使用它的示例非常少。
所以Allocation of variable-sized class 的回答提到堆栈分配无法调整大小。然而,以下内容是否有效?
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() 以分配更多内存在语法上是否有效(并且正确)? 这种方法会提供更好的性能(与使用 reserve() 的 std 向量相比),还是只会增加堆栈溢出的机会? 我的 Move 结构需要大约 28 字节的内存,我怀疑引擎将递归搜索(使用 alpha-beta)到最多 7 或 8 层,以便从堆栈中使用一些 28 * 35 * 8 ~ 8kb max。我在某处读到,通常堆栈的限制为 1Mb,所以这应该不会太多吧?
编辑:感谢下面的答案,我现在意识到我最初对 alloca() 所做的理解是错误的。但是,我仍然想知道是否可以通过以下方式使用 alloca():
int main()
{
int* arr = (int) alloca(sizeof(int));
arr = alloca(sizeof(int) * 2 ));//is this 'resizing' valid?
}
【问题讨论】:
-
为什么不直接使用
array或vector?例如Move* moves = new Move[10]; -
Why is alloca not considered good practice,加上
alloca不会调用 C++ 类的构造函数。 -
啊,如果可能的话,我想要一个快速移动生成器:) 您的评论实际上是我的问题的一部分。使用 alloca() 会比使用 reserve() 的 std 向量提供更好的性能吗?
-
"Resizing" 在您使用
alloca代表ints 的示例中是有效的,但它没有调整大小。您在堆栈上分配了两次 - 第一次是一个int的区域,第二次是两个ints 的区域。所以实际上你为三个ints 分配了内存。 -
@UserUnspecified 与此处的
malloc没有区别。最后一次调用后它指向[2],所以有两个元素。以前指向 [1] 的指针丢失了,因为它的地址在arr中,现在被替换了 - 但它仍然在堆栈上,正在消耗内存。与 malloc 的唯一区别是在返回时会被丢弃,而malloced 的值必须手动释放,否则会导致内存泄漏。