"Expression must have constant value" CPP [duplicate] - c++

#include <iomanip>
#include <iostream>
#include <Windows.h>
using namespace std;
template <class T>
void sort(int n, T a[]){
for(i=0;i<n-1;i++){
for(j=i;j<n;j++){
if(a[i] > a[j]){
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
}
void main(){
int size;
cout<<" Please input the amount of numbers you would like to sort"<<endl;
cin>>size;
int Amta[size];
for(int i=0; i<size; i++){
cout<<"Please enter the "<<size+1<< "number";
cin>>Amta[i];
}
Sleep(100000);
}
I am trying to get the how many numbers the user would like to input from the user and store it in the variable size.
But when I initialize array Amta[size] I get the following compile errors:
Expression must have constant value
and
C2057: expected constant expression" compile error.

You can't enter a non-constant value between the brackets when you declare your array:
int Amta[size];
Since you're getting size from the user, the compiler can't tell ahead of time how much memory it needs for Amta. The easiest thing to do here (especially for an exercise) is to just choose a relatively large value and make that the constant allocation, like:
int Amta[1024];
And then if you want to be careful (and you should) you can check if (size > 1024) and print an error if the user wants a size that's beyond the pre-allocated bounds.
If you want to get fancy, you can define Amta with no pre-set size, like int *Amta; and then you allocate it later with malloc:
Amta = (int *)malloc(sizeof(int) * size);
Then you must also free Amta later, when you're done with it:
free(Amta);

C++ doesn't allow variable length arrays. The size must be a constant. C99 does support it so if you need you can use a C99 compliant compiler. Some compilers like GCC and Clang also support VLA as an extension in C++ mode
But if C++ is a must then you can use alloca (or _alloca on Windows) to allocate memory on stack and mimic the C99 variable length array behavior
Amta = (int *)alloca(sizeof(int) * size);
This way you don't need to free the memory after going out of scope because the stackframe will automatically be restored. However you need to be very careful while using this. It's still better to use std::vector in C++ for these purposes

Related

Why do we declare the size of a single or a multi-dimensional array as a constant value?

Ever since I started the competitive programming, I always found that people always used to initialize the single or 2D arrays based on a constant maximum value from the maximum value of the input specification.
But I've always wondered why people do that when you can initialize the array based on the input.
For example, let's say a problem has an input specification of zero to ten to the power of five when receiving the input for the size of an array (or a vector).
Why do people do this:
Notation: The integer n represents the input, and a represents the array:
#include<bits/stdc++.h>
using namespace std;
const int MXN = 1e5;
int a[MXN], n;
int main() {
cin >> n;
for(int i = 0; i<n; i++)
cin >> a[i];
}
Instead of this:
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
int a[n];
for(int i = 0; i<n; i++)
cin >> a[i];
}
Or is this the best method (which is what I normally do):
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<int>a(n);
for(int i = 0; i<n; i++)
cin >> a[i];
//for(auto &i:a) cin >> i;
}
Is there any advantages of doing this? Thank you.
The 3 methods have their own advantage and disadvantage. The choice depends on the goal.
First method: a static storage duration array
The array last for the duration of the program execution,
Memory allocation is performed at program start up (probably by the os), and is very cheap
It does not provide value semantic. (It can't be easily copied, moved or assigned).
This method may be good for execution speed in small project but it is not scalable.
Second method: array allocated on the stack
The array life time start at its definition and end at the block scope exit
Memory allocation is performed during program execution and consist only of a very cheap assembly instruction.
It does not provide value semantic. (It can't be easily copied, moved or assigned).
It is a compiler extension to the standard language.
This method can be a good choice for temporary buffer, but once again it is not scalable, it is known to be a cause of stack overflow.
Third method: dynamically allocated array, std::vector
The array life time start and ends when needed,
Memory allocation is performed during program execution and is relatively expensive
It does provide value semantic. (It can easily copied, moved or assigned).
This should be the default choice.
The standard requires the array length to be a value that is compute-able at compile time so that the compiler is able to allocate enough space on the stack.
In your case, you're trying to set the array length to a value that is unknown at compile time. Yes, it seems obvious that it should be known to the compiler, but this is not the case here. The compiler cannot make any assumptions about the contents of non-constant variables.
This is one of the highlighted reason why we should use constants to declare the array size so that compiler would know how much memory on the stack should be allocated during creating the array.
For the dynamic allocation, either we may use data_type variable = new data_type[len] format or vector<>. Notice that the VLAs are supported in C99 (about the way you're trying to declare array like arr[n]).
As an instance, suppose if you tell the compiler
int vla = 100;
int a[vla];
The compiler would've no way of thinking how much memory you're actually going to need at runtime without doing a lot of very complex analysis to track down every last place where the values of vla changed.

myArray[N] where N = 1,000,000 returns an error whereas myArray[1,000,000] doesn't

File extension: .cpp
I have the following code:
int main() {
int N; cin >> N;
int myArray[N];
return 0;
}
I get an error when I'm trying to run that program if I input N as 1,000,000. However, when I set myArray[N] to myArray[1000000], it doesn't. Why does this happen?
int myArray[N]; is not valid in C++. This behavior was introduced in C99 but never in C++, possibly because it causes a lot of ugly stuff to happen behind the scenes in order to make it work, and it would make the generated code less efficient as a result. In fact this feature was even reversed in C11 where its support is merely optional and not mandatory anymore. Use std::vector<int> instead, or any similar standard container of your choice.
First of all VLA (variable length arrays) is an extension to C++. Compilers are supporting that since usually they support also C which has this functionality in standard.
Second problem this array is allocated on stack.
Stack has very limited size. So when your N has very big value application may crash since stack will overflow.
In this case you should use std::vector which will allocate data on heap.
Question is why array with static array size do not crash?
There can be couple reasons.
Compiler notices that array is not used and based on "As if" rule removes array.
Compiler knows size of the array at compile time, so required stack size is know. This information may be propagated to linker and application is build with bigger stack size then default value (in case of one suorce code application it may be possible). Disclaimer: this is my guessing, I didn't verified this in any form (by testing, or compiler documentation), but I've found this SO answer which confirms my suspicions.
The size of static arrays array[N] must be known at compile time.
Use std::vector for dynamic arrays:
// Example program
#include <iostream>
#include <string>
#include <vector>
int main()
{
int N; std::cin >> N;
std::cout << N << std::endl;
std::vector<int> myArray(N);
std::cout << myArray.size() << std::endl;
return 0;
}
That happens because size of static arrays must be known at compile time.
It is strongly recommended to use std::vector instead of arrays for more flexibility, and safety (this is always the answer: Use a vector if possible). You may use std::vector::reserve to request capacity be at least the length you want it to be. Use std::vector::capacity to see the current capacity.
#include <iostream>
#include <vector>
int main () {
std::vector<int> ivec;
ivec.reserve(100);
std::cout << ivec.capacity() << std::endl;
return 0;
}
Output:
100
Only if you have a very good reason to prefer arrays over vectors, you may dynamically allocate an array. Using std::shared_ptr makes this process much safer and convenient. Here's how it's done the way you want:
#include <iostream>
#include <memory>
int main () {
int N;
std::cin >> N;
std::shared_ptr<int> arr_ptr (new int[N], std::default_delete<int[]>());
for (int i = 0; i != N; ++i) {
arr_ptr.get()[i] = i * 2;
}
for (int i = 0; i != N; ++i) {
std::cout << arr_ptr.get()[i] << std::endl;
}
return 0;
}
Input:
10
Output:
0
2
4
6
8
10
12
14
16
18
That happens because, in C++, the size of static arrays declared with array[N] must be known at compile time and thus your error is propably your compiler which tells you that he must know the size inbeforehand. As stated use std::vector when you need dynamic arrays.

Stack overflow while using vector

I made a program for school's little contest, I have:
#include <iostream>
#include <vector>
int main(){
int n;
std::cin >> n;
int c[n];
std::vector<int> r(n);
std::cout << "I made it through";
//rest of program
}
When i type in 1000000 and press enter program crashes without a word, exit code (0xC00000FD). I presumed it happens when i initialize vector, but i though it can handle a lot more. Am i doing something wrong? I know i can use pointer but i'd prefer not to touch things that are already working.
The stack is a very restricted resource.
Even though your compiler seems to implement C-style VLA's in C++ (int c[n];), it does not magically gain more memory.
Test 1) Success of reading n, and 2) n not being out-of-bounds for your use before executing the statement allocating that stack-array.
Default stack-size for Windows: 1MB sizeof(int): 4 Thus, about 250000 fit.
Default stack size for Linux: 8MB sizeof(int): 4 Thus, about 2000000 fit.
Workaround: Use dynamic allocation for the ints, like with a std::vector:
std::vector<int> c(n);
Alternatively, at least use a smart-pointer:
std::unique_ptr<int[]> c(new int[n]);
The problem isn't vector (which uses the heap for its underlying expanding storage in most STL implementations), but int c[n], which will allocate 1,000,000 4-byte integers in the stack, which is almost 4MB. On Win32 the stack is by default around 1MB, hence the overflow.
If you really need to use an array then change your c array to be allocated on the heap by using new, but don't forget to delete[], otherwise use of vector is preferred for most expanding storage scenarios. If you need a fixed-length array then consider array<class T, size_t N> (new in C++11) which adds bounds-checking.
You probably just need to allocate the array dynamically. In C++
#include <iostream>
#include <vector>
int main()
{
int n;
std::cin >> n;
int *c = new int[n];
if(nullptr == c) {
std::cerr << "Runtime error" << std::endl;
return 1;
}
std::vector<int> r(begin(n), end(n));
std::cout << "I made it through";
delete[] c;
return 0;
}
Also to make the vector after you have allocated c dynamically you can use begin, end

Array size declaring dynamically in c and c++

I'm passing the array size dynamically through a variable named size, it's working fine in c but not in c++. Please tell me the reason, Thanks in advance.
#include <iostream>
#include <stdlib.h>
using namespace std;
int size;
int main(int argc, char *argv[])
{
int i ;
int *a[size];
cout<<"Enter size";
cin >> size;
for(i =0; i < size ;i++)
{
cout<<"Enter value:" ;
cin>>a[i] ;
}
for(i=0 ; i < size; i++)
{
cout<<a[i]<< " ";
}
system("PAUSE");
return 0;
}
I have executed the same program with proper I/O changes, its executed properly.
Also please help me in understanding how compiler is behaving in this case at the time of array declaration.
Please tell me the reason
The reason is that C++ doesn't have variable-length arrays. Perhaps you are looking for std::vector<int> (likely) or new int (unlikely).
Also please help me in understanding how compiler is behaving in this case at the time of array declaration.
Just like it behaves in any other case: it parses the source text and outputs machine code of which the semantics correspond to that of the source code. It's just that the size of a variable-length array is not hard-coded as a constant, instead it is stored in a register or on the stack (like some sort of "variable"), and size calculations (pointer arithmetic, in particular) are performed agains that stored value.
Your code tries to allocate an amount of memory from an uninitialized variable size. Its value is assigned only later:
int a[size];
/* ... */
cin >> size;
If you switch the order of these statements, it might do what you want, if your C++ compiler has an extension for variable length arrays. A more portable and generally preferable solution would be:
cin >> size;
std::vector<int> a(size);
Edit: You probably want an int[] not *int[].
You cannot create variable length arrays in c++. try using vectors instead
There are no VLAs in C++.
If you want to write your code to be used in a C++ project, then write your code in C++ (use std::vector instead of VLAs) or write your code in C, compile it with a C compiler and use your linker to link to it from your C++ project.
int *a[size]; by this statement you want to create a array of size size , but you have not initialized the variable size.C++ doesn't support variable length array.You can do it by this:
int size;
cin>>size;
int *a[size];
or just use STL vector which allocates memory dynamically.
vector<int>a;
and to put value in the vector just push back the values
a.push_back(56);
For more about vector check out this link

Can't set variable length with variable

What I'm trying to do right now is to create an array with a length that is defined by a variable. However, when I put the variable in the array length, it gives me a "Variable length array of non-POD element type 'glm::vec2'" error. However, if I replace the variable with an actual number, the error goes away. Why does this happen and how can I fix this?
int numtriangles = sector1.numtriangles;
glm::vec2 tex[test]; //Using a variable generates an error
glm::vec3 vertices[10]; //No error here
You cannot have variable length arrays(VLA) in standard C++.
Variable length arrays are not allowed by the C++ Standard. In C++ the length of the array needs to be a compile time constant. Some compilers do support VLA as a compiler extension, but using them makes your code non-portable across other compilers.
You can use, std::vector instead of an VLA.
See this question Is there a way to initialize an array with non-constant variables? (C++)
Short answer is no you cannot directly do this. However you can get the same effect with something like
int arraySize = 10;
int * myArray = new int[arraySize];
Now myArray is a pointer to the array and you can access it like an array like myArray[0], etc.
You can also use a vector which will allow you to have a variable length array. My example allows you to create an array with a variable initailizer however myArray will be only 10 items long in my example. If you aren't sure how long the array will ever be use a vector and you can push and pop items off it.
Also keep in mind with my example that since you've dyanmically allocated memory you will need to free that memory when you are done with the array by doing something like
delete[] myArray;
Here is a little sample app to illustrate the point
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int arraySize = 10;
int * myArray = new int[arraySize];
myArray[0] = 1;
cout << myArray[0] << endl;
delete[] myArray;
}
use STL.
IF you want a variable length array you can use vectors under #include<vector>
Native c++ array donot nave variable length array.
When you declare an array with a length specifier, only constants are allowed.
Actually it's when the program is compiled that the array length is evaluated.
Note however that it's illegal in C++ to declare int test[]; like the compiler has no way to know how much space to allocate for the variable.
Without a length specifier, there is no actual memory that is reserved for the array, and you have to resort to using pointers and dynamic memory allocation:
int * test = new int[12];
// or
int * test = new int[val]; // variable works here
// and don't forget to free it
delete [] test;
Using int test[12] actually creates an array that is statically initialized once and for all to contain 12 integers at compile time.
Do not ever attempt to do delete [] test with a variable declared this way, as it's most certainly going to make your program crash.
To be precise, if the array is declared in a function, it will use space on the program stack, and if declared in a global context, program data memory will be used.
C++ doesn't support declare variable length array. So to use a array with a length you may
Assume
a big number which is highest possible length of your array. Now declare an array of that size. And use it by assuming that it an array of your desire length.
#define MAX_LENGTH 1000000000
glm::vec2 tex[MAX_LENGTH];
to iterate it
for(i=0; i<test; i++) {
tex[i];
}
Note: memory use will not minimized in this method.
Use pointer and allocate it according your length.
glm::vec2 *tex;
tex = new glm::vec2[test];
enter code here
for(i=0; i<test; i++) {
tex[i];
}
delete [] tex; // deallocation
Note: deallocation of memory twice will occur a error.
Use other data structure which behave like array.
vector<glm::vec2> tex;
for(i=0; i<test; i++){
tex.push_back(input_item);
}
/* test.size() return the current length */