0

I used to believe that for stack allocated arrays, its size has to be defined at compile time. I always use either std::vector or the new[] operator if the size of the array is not known beforehand.

However, recently I came across C++ code which compiled and executed fine even when the size of the array was not known at compile time. I've gone through a similar question on this but I've still not got the clarity in my mind on this.

I tried the following code online at cpp.sh. I don't understand the output I'm getting.

Code

#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;

}

Output

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

If it's not valid in C++, why does it even compile? And how is it that I can take 3 integers as input in arr1 but it's size is 1?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Vishal Sharma
  • 1,670
  • 20
  • 55
  • You might be missing something very important -- `sizeof(x)` tells you the size to represent x's type, not x's value. since `arr1` is of type `int[]`, to find `sizeof(arr1)==1` surprising, you have o think `sizeof(int[])` should be something else. But what? – David Schwartz May 11 '19 at 06:11
  • Variable-length arrays are a **non-standard** extension implemented in some C++ compilers (gcc and clang) but not in all. `sizeof()` is evaluated only at compile-time, but VLAs are allocated at runtime, so it makes sense that `sizeof(arr1)` doesn't report the right size you are expecting. You should not use VLAs at all, stick with `std::vector` instead – Remy Lebeau May 11 '19 at 06:17
  • @Tomothy32 I had already mentioned the question you're referring, in my question itself and I have mentioned there that I didn't get enough clarity from that. – Vishal Sharma May 11 '19 at 06:21
  • @DavidSchwartz I was expecting a similar output like I got for arr2. – Vishal Sharma May 11 '19 at 06:25
  • 1
    @VishalSharma *If it's not valid in C++, why does it even compile?* -- [Use a different compiler](https://rextester.com/GOT74713). One of the most used compilers, Visual Studio, has never accepted VLA's. That is more of a reason to drop using them, in case you happen to use Visual Studio (even the latest Visual Studio 2019) now or in the future. – PaulMcKenzie May 11 '19 at 06:45
  • 1
    @VishalSharma Whatever reason you can use to argue that `sizeof(int[])` and `sizeof(int[2])` can be the same equally well argues that `sizeof(int[])` and `sizeof(int[430])` should be the same. So your expectation of a similar answer as the one you got for `arr2` is really not reasonable. One type has a well-defined number of characters needed to represent it and the other is arbitrary. – David Schwartz May 11 '19 at 07:19

1 Answers1

3

GCC has an extension which allows stack arrays of variable size. This is non standard, and as far as I'm aware only works with GCC, and will lead to stack overflows if you try to create large arrays.

sizeof is always evaluated at compile time, it can't know the size of the array so it just returns 1.

Stick to using std::vector for variable sized arrays.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • [Clang also supports VLAs](https://clang.llvm.org/compatibility.html#vla). And it should be noted that VLAs are non-standard only in C++, but are standard in C99. – Remy Lebeau May 11 '19 at 06:16