I'm attempting the Latin Square Daily Challenge on Reddit and I wanted to use an array which allocates size during run-time by using the following code:
int n;
cout << "Please enter the size of the Latin Square: ";
cin >> n;
int latinsquare[n][n];
This works in online compilers but not in Visual Studio 17. Is there a way to do this in the Microsoft C++ compiler?
This is because variable-length arrays are non-standard in C++ (why?). You can allocate latinsquare using new, but an idiomatic way of doing it in C++ is to use a vector of vectors:
std::vector<std::vector<int>> latinsquare(n, std::vector<int>(n, 0));
VLA is not a part of c++ standard. If you want to use them you need compiler extension.
But you may
Create it dynamically via new and delete operators
Use std::vector
Related
I was wondering what are some alternatives to doing the following code snippet in c++.
int i;
cin >> i;
int arr[i];
I have recently started looking into competitive programming and trying to learn more.
EDIT: For those comments about this not being cpp. It compiles successfully with the makefile I am using in my class which is using gcc -std=c++11 -o a.exe main.cpp and returns to the console when I input a length of 1
array length: 1
You should use std::vector instead in C++, e.g.
int i;
cin >> i;
std::vector<int> arr(i);
BTW: VLA is not supported by C++ standard. Also see Variable Length Array (VLA) in C++ compilers
One way is:
int i = 0;
cin >> i;
auto arr = std::make_unique<int[]>(i); // #include <memory>
// Or: std::make_shared<int[]>(i);
Another way is to use std::vector:
int i = 0;
cin >> i;
std::vector<int> arr(i); // #include <vector>
Your code is not C++. It uses a C language feature (from the C99 version of the C standard) called "variable-length arrays" - where arrays on the stack can have a length determined at run-time.
Variable-length arrays are considered are dangerous and considered a rather bad idea; see:
Why aren't variable-length arrays part of the C++ standard?
If you compile your code while telling the compiler to only accept standard-compliant code, it will fail: gcc -std=c++11 -pedantic-error. Try it on GodBolt.
In C++ the size of an array is set at compile-time, period. Like other users suggested, you can use dynamic allocation to obtain a run-time-determined-length contiguous area in memory, of your choice of size: Using std::vector, std::unique_ptr, std::shared_ptr or even plain allocation with new (although the latter is not recommended).
So simple code like:
int n;
cin >> n;
int s[n], p[2*(n-1)][3];
I have to translate to:
int n;
cin >> n;
vector<int> s(n, 0);
vector<vector<int>> p(2 * (n - 1), vector<int>(3));
I would like to see something like:
int n;
cin >> n;
mat s(n), p(2*(n-1), 3);
I definitely do not want to use new\make_unique and std::array+std::vector mix for such simple stuff. Two lines are an ugly mess IMHO so I seeek for a way to keep C like sintax.
So what is a workaround? Any define/standard header/copy-pastable STL based C++ type?
Variable length arrays are not supported by standard C++.
std::vector<int> is the idiomatic way of implementing a contiguous block of int data whose size is not known at compile time. A good rule of thumb is to use std::vector until you find a compelling reason not to.
Variable length arrays (i.e. arrays where at least one dimension is not a compile time constant) are not supported in standard C++. Hence, you cannot write something like cin >> n; int s[n].
Some extensions exist, but still - for very large values of n, you might get troubles if the compiler at hand puts such an array on the "stack", which is usually more limited than the heap.
The standard way is to use std::vector<int> s(n) or, if - though usually not recommended - for some reason you want a "plain" array not wrapped by an object, you could write int *s = new int[n];, although it is then incumbent on you calling delete[] s; when you no longer need the array.
alloca is another alternative. Not standard but widely supported.
By standard C++, there's no Variable Length Arrays (VLAs). Either use an STL like std::vector, or define the variables as const (that you can't modify at runtime).
I have started learning c++. I read that an array's size can only be set before run and dymanic arrays can be set during runtime. So I was expecting this to fail but it didn't:
#include <iostream>
int main() {
using namespace std;
int size;
cout << "enter array size:";
cin >> size;
int i, score[size], max; //array size set to variable doesn't fail
cout << endl << "enter scores:\n";
cin >> score[0];
max = score[0];
for (i = 1; i < size; i++)
{
cin >> score[i];
if (score[i] > max)
max = score[i];
}
cout << "the highest score is " << max << endl;
return 0;
}
Is this a new feature in recent C++ compilers? Is it realising I need a dynamic array and creating that instead?
Probably you are using GCC compiler, it has an extension called Arrays of Variable Length.
std::vector is the real dynamic arrays in C++.
To select this standard in GCC, use the option -std=c++11; to obtain all the diagnostics required by the standard, you should also specify -pedantic (or -pedantic-errors if you want them to be errors rather than warnings).
In all current and past standards, that code is ill-formed. Variable Length Arrays are a C99 feature not a C++ feature, although some compilers do provide it as an extension. In the upcoming standard (expected to be C++14, currently in the process of review) a similar feature by other name (and slightly different semantics) has been adopted, so expect this to become standard in the future.
Note that in general, that is, excluding arrays of runtime bound (as they are named in the upcoming standard), the size of the array is part of the static type of the object and known at compile time. In the case of VLAs or array of runtime bound, the size is not known at compile time and thus the type is somehow of a second class citizen among types. The implication is that you cannot use VLAs/ARB with templates (as code generation for the template depends on the type, which includes the size, which is unknown at compile time).
In the same way there are other limitations, sizeof is not a compile time operation for VLAs, and it is not even allowed for ARB, these form of arrays can only be used for objects with automatic storage duration (i.e. in the stack), you cannot take the address of the array (although you can take the address of the first member),...
Another important point to consider is that the standard does not guarantee that the memory for an ARB will be allocated on the stack, and allows implementations to call a global allocation function, although the intention is that compilers will catch up and provide the space from the stack.
Be careful! Undefined integers are not guarenteed to be any value at all. Some compilers will default to 0, while others will use whatever garbage bits where already in memory. For this reason Visual Studio wouldn't even let me compile. Step through your code to see the allocated memory for score before you set the size variable. Likely size as it is compiled is a random integer from garbage memory, which means it can change every time you execute!
A C style array needs to know how much continuous memory to allocate. This allows for direct indexing, and other optimizations. As others have suggested, std::vector is what is the standard dynamic container in C++, which uses an array under the hood.
This question already has answers here:
In C++ books, array bound must be constant expression, but why the following code works?
(2 answers)
Closed 9 years ago.
When I started programming with C++ I was learned to allocate the array size by using dynamic memory allocation as follows:
int main()
{
int nArrayLength;
cout << "Enter an array length: ";
cin >> nArrayLength;
int *nArray = new int[nArrayLength];
// contents
delete[] nArray;
return 0;
}
Now I tried the following code using Code::Blocks 12.11 with the mingw32-g++ // GNU GCC compiler.
int main()
{
int nArrayLength;
cout << "Enter an array length: ";
cin >> nArrayLength;
int nArray[nArrayLength];
return 0;
}
This also works fine.
Therefore, why should I use dynamic memory allocation in this case when the easier method also works fine?
You should use neither.
The first is valid, but it's C-style code. The second is non-standard code - it's accepted by that compiler because of some extension.
Use a std::vector instead:
#include <vector>
int main()
{
int nArrayLength;
cout << "Enter an array length: ";
cin >> nArrayLength;
std::vector<int> nArray(nArrayLength);
return 0;
}
A vector has the same semantics as an array, it can grow dynamically (and automatically), and does all the pesky memory management under the hood.
The second code is not valid standard C++. It uses a compiler extension called variable length arrays. See the GCC documentation.
However, there is a proposal for variable length arrays with automatic storage duration that has been adopted for C++14.
Compile the second code with -pedantic option if you're using GCC. It would not compile.
It is because it is not Standard conformant. Variable Length Array (VLA) is not in the Standard C++. It is a compiler extension.
Sometimes you don't know the size of your array beforehand, so you need to allocate storage for it that may grow or shrink dynamically. You should use std::vector because it manages the array storage transparently.
If you are forced to use C-style arrays, use them like in the first code snippet, the second one is not standard C++.
It depends whether you want to use the stack or the heap.
You can also use auto_ptr if you want your heap allocation to be released automatically when scope goes out.
I want to initialize an array with a size using a value I read into an integer variable.
I cant seem to understand why it works in Dev-C++ but not in Turbo C++. Here's the code to help make things clear
int arr_size; //cin max value for lets say number of students or something...
cin >> arr_size;
int array[arr_size]; // declares array with size (assume 10 or 100) with range 0 to 9 or 0-99
The compiler shows an error in Turbo C++ (really old, I know, but my school uses it unfortunately). Dev-C++ and codeblocks doesnt.
Why is that so? I know its bad practice "as they define it in some books" to have an array size the same as an int value, but is there a work around for this in Turbo C++?
I want to know why the error happens and how I can get a work around it ... thanks a lot!
The C++ standard only permits arrays to be sized with a constant expression. (However, some compilers may offer it as a non-standard language extension.)
You could use a std::vector instead:
std::vector<int> array(arr_size);
Or you could dynamically-allocate memory manually:
int *const array = new int[arr_size];
...
delete [] array; // Remember to delete when you're done
Variable length arrays are not allowed in standard c++. You can do it in C99. Consider using C++ std::vector as :
std::vector<int> array(arr_size);
And you can index it exactly like the array if you have to.
The workaround is to dynamically allocate this array, making sure to delete the memory when done.
int arr_size; //cin max value for lets say number of students or something...
cin >> arr_size;
int *arr = new int[arr_size];
//use the array as needed
delete [] arr;
You want variable length array (VLA) which is not allowed in C++. Its allowed in C99.
Use std::vector<int> instead, as:
int arr_size;
cin >> arr_size;
std::vector<int> array(arr_size);