Variable Length Array (VLA) is not part of C++ standard. It is part of C99 standard, and typically implemented as an extension for C++ in various compilers.
It is typically ok to use a VLA in a C++ program when you allocates an array. But you are going to have problems when you need to pass the array around, because there is no argument type that is VLA so that you can pass it as arguments to functions in C++. (That's why when you manually inline the function, the code runs ok, which avoids passing the array into a function.) You have to pass the array as a pointer to the function, and maybe use reinterpret_cast
before and inside the function to convert the VLA to a pointer, and convert it back. It is simply terrible code.
When coding in C++, just use the C++ idiomatic way. Since you already use vector
, you can just use vector<vector<int>>
(vector<vector<int> >
if not using C++11, but from the way you initialize x
, you are using C++11) as a 2-D array. Your code should be modified as below:
#include <iostream>
#include <vector>
using namespace std;
void print_2d_array(int arr_size, vector<vector<int>> &arr){
for(int i = 0; i < arr_size; ++i){
for(int j = 0; j < arr_size; ++j)
cout << arr[i][j] << "\t";
cout << endl;
}
}
int main(){
vector<int> x{10,15,20,30,40};
vector<vector<int>> arr(x.size(), vector<int>(x.size()));
// No need to use this to initialize:
// for(int i = 0; i < sizeof(x); ++i)
// arr[i][i] = 0;
print_2d_array(5, arr);
return 0;
}
Note that this also fixed your problem that your arr
was not properly initialized.
If you are going to use C, then VLA is totally ok, and it will be like this (and not that I didn't fix your initialization, which only initialized the diagonal elements. You have to use a C, not C++ compiler to compile this.):
#include <stdio.h>
void print_2d_array(int arr_size, int arr[][arr_size]){
for(int i = 0; i < arr_size; ++i){
for(int j = 0; j < arr_size; ++j)
printf("%d\t", arr[i][j]);
printf("\n");
}
}
int main(){
int x[] = {10,15,20,30,40};
int arr[sizeof(x)][sizeof(x)];
// bad initialization:
for(int i = 0; i < sizeof(x); ++i)
arr[i][i] = 0;
print_2d_array(5, arr);
return 0;
}
Ok, if you decide to use C++ but don't like vector, the next simplest thing is to use primitive pointers, which is not recommended.
#include <iostream>
#include <vector>
using namespace std;
void print_2d_array(int arr_size, int **arr){
for(int i = 0; i < arr_size; ++i){
for(int j = 0; j < arr_size; ++j)
cout << arr[i][j] << "\t";
cout << endl;
}
}
int main(){
vector<int> x {10,15,20,30,40};
int **arr = new int*[x.size()];
for (int i = 0; i < x.size(); ++i) {
arr[i] = new int[x.size()];
for (int j = 0; j < x.size(); ++j) {
arr[i][j] = 0;
}
}
print_2d_array(5, arr);
for (int i = 0; i < x.size(); ++i) {
delete[] arr[i];
}
return 0;
}
Save your trouble and use containers. You are using modern C++.
(The answer assumes you couldn't determine the size of the array before running. Although this is not the case in your example--the size must be 5 and there is no reason to use VLA.)