【问题标题】:Getting 0 as the size of stack allocated array whose size is given at runtime获取 0 作为堆栈分配数组的大小,其大小在运行时给出
【发布时间】:2019-05-11 05:52:51
【问题描述】:

我曾经认为对于堆栈分配的数组,它的大小必须在编译时定义。如果事先不知道数组的大小,我总是使用std::vectornew[] 运算符。

但是,最近我遇到了 C++ 代码,即使在编译时不知道数组的大小,它也能很好地编译和执行。我在this 上遇到了类似的问题,但我仍然没有清楚地了解这一点。

我在cpp.sh 在线尝试了以下代码。我不明白我得到的输出。

代码

#include <iostream>
using namespace std;

int main()
{
  int n;
  cout<<endl<<"Enter the size of arr1: ";
  cin>>n;
  int arr1[n];

  cout<<endl<<"Enter the elements of arr1 below"<<endl;

  for(int i=0;i<n;++i)
  cin>>arr1[i];

  cout<<endl<<"Size of arr1: "<<sizeof(arr1)/sizeof(arr1[0]);  
  cout<<endl<<"sizeof(arr1): "<<sizeof(arr1);
  cout<<endl<<"sizeof(arr1[0]): "<<sizeof(arr1[0])<<endl;

  int arr2[3];
  cout<<endl<<"Size of arr2: "<<sizeof(arr2)/sizeof(arr2[0]);
  cout<<endl<<"sizeof(arr2): "<<sizeof(arr2);
  cout<<endl<<"sizeof(arr2[0]): "<<sizeof(arr2[0])<<endl;
  return 0;

}

输出

Enter the size of arr1: 3

Enter the elements of arr1 below
1 3 5

Size of arr1: 0
sizeof(arr1): 1
sizeof(arr1[0]): 4

Size of arr2: 3
sizeof(arr2): 12
sizeof(arr2[0]): 4

如果它在 C++ 中无效,为什么还要编译?为什么我可以在 arr1 中输入 3 个整数,但它的大小是 1?

【问题讨论】:

  • 您可能遗漏了一些非常重要的东西——sizeof(x) 告诉您表示 x 类型的大小,而不是 x 的值。因为arr1int[] 类型,所以发现sizeof(arr1)==1 令人惊讶,你有o 认为sizeof(int[]) 应该是别的东西。但是什么?
  • 可变长度数组是在某些 C++ 编译器(gcc 和 clang)中实现的非标准扩展,但并非全部。 sizeof() 仅在编译时评估,但 VLA 是在运行时分配的,因此 sizeof(arr1) 没有报告您期望的正确大小是有道理的。您根本不应该使用 VLA,而是坚持使用 std::vector
  • @Tomothy32 我已经在我的问题本身中提到了您所指的问题,并且我在那里提到我没有从中获得足够的清晰度。
  • @VishalSharma 如果它在 C++ 中无效,为什么还要编译? -- Use a different compiler。最常用的编译器之一 Visual Studio 从未接受 VLA。如果您现在或将来碰巧使用 Visual Studio(甚至是最新的 Visual Studio 2019),这也是放弃使用它们的更多原因。
  • @VishalSharma 无论你用什么理由来争辩sizeof(int[])sizeof(int[2]) 可以相同,都可以很好地证明sizeof(int[])sizeof(int[430]) 应该相同。因此,您期望得到与arr2 类似的答案确实是不合理的。一种类型具有明确定义的字符数来表示它,而另一种则是任意的。

标签: c++


【解决方案1】:

GCC 有一个扩展,它允许可变大小的堆栈数组。这是非标准的,据我所知仅适用于 GCC,如果您尝试创建大型数组,则会导致堆栈溢出。

sizeof 总是在编译时计算,它不知道数组的大小,所以它只返回 1。

对于可变大小的数组,坚持使用std::vector

【讨论】:

猜你喜欢
  • 2016-08-26
  • 2018-06-29
  • 2014-06-12
  • 1970-01-01
  • 2020-10-20
  • 2014-05-17
  • 2013-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多