【问题标题】:c++ static array declaration from function parameter来自函数参数的c ++静态数组声明
【发布时间】:2019-08-28 10:17:05
【问题描述】:

我知道当我这样做时

int x;
cin >> x;
char arr [x];

根据 c++ 标准,它是病态的,因为 c++ 不允许可变大小的静态数组。

我的问题是,如果我在函数范围内声明静态数组,函数参数的大小可变,它仍然是不正确的吗?还是在标准中明确定义?

void foo(int size)
{
    char arr [size];
    // do something
}

void main()
{
   foo(10);
   foo(20);
}

【问题讨论】:

  • 为什么不std::stringstd::vector<char>
  • 在你的两个例子中,数组的大小是可变的——它不会起作用。
  • 您似乎在使用可变长度数组编译器扩展,不,这不是标准 c++,无论是否在函数内部
  • "... 不允许可变大小的静态数组..." 更正:"... 不允许可变大小的数组... "

标签: c++ string vector containers


【解决方案1】:

对于初学者,您没有“静态数组”。您的示例中使用的数组具有自动存储持续时间。而允许可变长度数组的 C 语言要求此类数组具有自动存储持续时间。

可变长度数组不是 C++ 的标准特性。

改为使用标准容器std::vector。或者,如果您使用的是字符串,则使用标准类 std::string

例如

#include <iostream>
#include <string>

void foo(int size)
{
    std::string s;
    s.resize( size );
}

int main()
{
   foo(10);
   foo(20);
}

【讨论】:

  • 使用std::stringstd::vector不会避免堆分配。根据参数在函数中声明数组时,应该只是简单地从函数序言中的堆栈指针中减去该参数,对吧?
  • @sfgr C++ 标准没有包含 C 中的这个特性。
【解决方案2】:

这不是有效的 C++ 代码:

char arr [size];

它可能适用于某些支持 C 的可变大小数组作为扩展的编译器。

数组也不是静态的,如果 size 在编译时已知是常量,则它是自动的。

它在函数范围和其他任何地方都无效。

您可以使用标准容器,例如支持可变大小的vector,甚至是std::string

【讨论】:

    【解决方案3】:

    foo 被调用时,一个新的堆栈帧被压入堆栈,它为foo 范围内的所有局部变量保留足够的空间以适应。如果要从foo 中调用另一个函数bar,它的堆栈帧将被推到foo 的顶部。为使其(有效地)工作,编译器必须知道堆栈帧的大小(通过扩展,foo 中的所有局部变量,包括数组 arr)。

    当函数返回时(首先是bar,然后是foo),它们的堆栈帧会按照它们创建的相反顺序弹出,因此堆栈内存始终保持碎片整理,每个局部变量的位置都是在编译时确定,因此相对效率。堆内存可以具有动态大小,但这是以必须在堆上分配适当大小的位置为代价的。

    您还可以在标准库容器std::vectorstd::array 中看到这种二分法。 std::array 实际上只是 C 样式数组的包装器,因此需要在编译时知道它的大小,因此指定为模板参数,例如std::array&lt;char, 42&gt; 包裹 char[42]与您的情况不同,如果您使用运行时变量作为第二个模板参数,编译器会(正确地)抱怨。但是,您可以安全地使用任何常量表达式(例如 constexpr 函数的结果)。

    【讨论】:

      猜你喜欢
      • 2015-07-29
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 2017-03-25
      • 2020-06-16
      • 2013-09-10
      • 2017-06-22
      • 1970-01-01
      相关资源
      最近更新 更多