C++ 我需要将数组声明为静态局部变量吗?

C++ 我需要将数组声明为静态局部变量吗?,c++,arrays,variables,static,allocation,C++,Arrays,Variables,Static,Allocation,假设我有一个我经常调用的函数,其中包含一个数组: char foo[LENGTH]; 根据长度的值,每次调用函数时分配该值可能会很昂贵。我看到: static char foo[LENGTH]; 因此,它只分配一次,并且始终使用该数组: 这是阵列的最佳实践吗 编辑: 我已经看到一些反应,静态局部变量不是最好的。但是初始化成本呢?如果我打电话: char foo[LENGTH] = "lorem ipsum"; 难道不是每次调用函数时都要复制的吗?长度应该是编译时常数C++,没有c99 vL

假设我有一个我经常调用的函数,其中包含一个数组:

char foo[LENGTH];
根据长度的值,每次调用函数时分配该值可能会很昂贵。我看到:

static char foo[LENGTH];
因此,它只分配一次,并且始终使用该数组:

这是阵列的最佳实践吗

编辑:

我已经看到一些反应,静态局部变量不是最好的。但是初始化成本呢?如果我打电话:

char foo[LENGTH] = "lorem ipsum";

难道不是每次调用函数时都要复制的吗?

长度应该是编译时常数C++,没有c99 vLA,fo只会在栈上使用空间。非常快。

分配一个原始数据类型且具有自动存储持续时间的对象通常不是什么大问题。问题更多:您是否希望foo的内容在函数的执行过程中继续存在

例如,考虑以下函数:

char* bar() {
   char foo[LENGTH];
   strcpy(foo, "Hello!");
   return foo;  // returning a pointer to a local variable; undefined behaviour if someone will use it.
}
在这种情况下,foo将超出范围,在bar完成后将无法合法访问

但是,如果你写信,一切都好

char* bar() {
   static char foo[LENGTH];
   strcpy(foo, "Hello!");
   return foo;  // foo has static storage duration and will be destroyed at the end of your program (not at the end of bar())
}

如果具有自动存储持续时间的大型变量变得太大以至于超过了有限的堆栈大小,或者如果递归调用该函数,则可能会出现具有自动存储持续时间的大型变量的问题。然而,为了克服这个问题,您需要使用动态内存分配,即new/delete。

首先,自动分配字符数组的时间并不取决于它的大小,在任何合理的实现中,递增堆栈指针的时间复杂度是恒定的,这是非常快的。请注意,即使对于VC++中没有有效的VLA,这也一样,只有增量才是运行时操作数。另外请注意,如果您的数组将被初始化,则答案将不同

因此,您所指的性能缺陷实际上并不清楚

另一方面,如果将所述数组设置为静态,则在所提供的示例中不会招致任何惩罚-因为char未初始化,因此不会有阻止静态变量双重初始化的正常同步。但是,您的函数可能会变得线程不安全


一句话:过早优化是罪恶的根源。

很抱歉,我将目标帖子移动了一点。。。但是初始化呢?这会改变我们的偏好吗?你应该问这个问题,因为这将是一个完全不同的答案。我不认为大小是一个问题。我相信编译器已经可以帮我处理了。如果这个太大,它将处理把它放在堆上的问题。不,编译器不会这样做。它将在堆栈上,当长度变大时,您可能会在没有任何警告的情况下遇到问题。@JonathanMee,不,不会。如果数组增长超过允许的堆栈大小,您将有。。。猜猜看。。。堆栈溢出!然而,斯蒂芬错了。静态字符foo[LENGTH];永远不会在堆栈上分配。如果有的话,答案应该是相反的——大型自动变量会造成堆栈溢出的风险,而静态变量则不会。@SergeyA:对;局部变量是错误的术语;已更正为自动存储持续时间。移动球门柱的向下投票。@Bathsheba我的拉丁语是week。你能翻译一下吗?@JonathanMee关于你的编辑,如果你想修改函数中的foo,你必须手动重置它,否则它可能仍然有上一次迭代的修改内容。我认为这是不可取的,因为如果它是可取的,那么从一开始就必须使用static,这是毫无疑问的。如果不想修改foo,可以使用const char*foo。无论哪种情况,静态都没有帮助。请注意,您的编辑使已提供的回答原始问题的4个答案无效。无需道歉。只需接受这个问题的一个答案,恢复您的更改并问一个新的。是的,我在问了以下问题后移动了目标帖子:我真的想知道初始化,使用静态局部变量有意义吗?不需要道歉。只需接受此问题的其中一个答案,恢复您的更改并询问新的答案。