Can we create variable length arrays in c++ - c++

I am trying to create this simple program which displays the data of the array back to the user again.. I want to create a variable length array. In this program the user is first asked the number of elements of the array followed by the data.
The problem is that in some of the IDE this code runs completely fine but in others it gives the error that variable length array is not allowed.... So what is correct?
void main()
{
int t;
cin>>t;
int ar[t];
for(int i=0;i<t;i++)
{
cin>>ar[i];
}
for(int i=0;i<t;i++)
{
cout<<ar[i]<<"\t";
}
}
For eg. This doesn't work in Turbo C++... But runs in this IDE's
http://www.tutorialspoint.com/compile_cpp11_online.php
https://www.codechef.com/ide

Standard C++ does not support variable length arrays. Some implementations provide it as an extension but as you have already found out, relying on them makes for non-portable code.
I recommend you use a std::vector instead. It works with pure standard C++.
int size;
if (!(std::cin >> size) || (size < 0))
throw std::invalid_argument {"bad size"};
std::vector<int> numbers (size);
In GCC and Clang, you can use the -pedantic compiler switch to turn off any non-standard extensions. This will help you avoid accidentally writing non-portable code. Of course, you should also compile with -Wall, -Wextra and -Werror.

Related

Constant value error in array declaration

While writing my code on Visual Studio 2022, I came across the error (E0028) that the expression must have a constant value in line 11.
#include <iostream>
using namespace std;
int main()
{
int n;
cout<<"Enter"<<endl;
cin>>n;
int a[n]; //error line
for(int i = 0; i<n; i++)
{
cin>>a[i];
}
for(int i = 0; i<n; i++)
{
cout<<" "<<a[i];
}
return 0;
}
But when I put the same code in any online compiler, it worked fine. How does this happen? Also how to resolve the issue in Visual Studio 2022.
What I have tried:
I think that the best way to deal with this is dynamic array allocation using vectors, but I would like to hear your views. Also, why don't we have the same error in online compilers?
The size of an array variable must be compile time constant. n is not compile time constant, and hence the program is ill-formed. This is why the program doesn't compile, and why you get the error "expression must have a constant value".
But when I put the same code in any online compiler, it worked fine. How does this happen
This happens because some compilers extend the language and accept ill-formed programs.
how to resolve the issue in Visual Studio 2022.
Don't define array variables without compile time constant size.
I think that the best way to deal with this is dynamic array allocation using vector
You think correctly. Use a vector.
In the C99 version of the C standard variable-length arrays are allowed,
No version of C++ allows them;
When you said online compiler did you mean ideone.com?
ideone as I know uses gcc of Cygwin, there C++ (gcc 8.3) as well as C++14 (gcc 8.3) allows varaiable length array which is non-standard
#include <iostream>
using namespace std;
int main() {
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++){
a[i]=i*i;
cout<<a[i]<<endl;
}
return 0;
}

Is there is any way that i can define user input as my string array length? [duplicate]

I am trying to create this simple program which displays the data of the array back to the user again.. I want to create a variable length array. In this program the user is first asked the number of elements of the array followed by the data.
The problem is that in some of the IDE this code runs completely fine but in others it gives the error that variable length array is not allowed.... So what is correct?
void main()
{
int t;
cin>>t;
int ar[t];
for(int i=0;i<t;i++)
{
cin>>ar[i];
}
for(int i=0;i<t;i++)
{
cout<<ar[i]<<"\t";
}
}
For eg. This doesn't work in Turbo C++... But runs in this IDE's
http://www.tutorialspoint.com/compile_cpp11_online.php
https://www.codechef.com/ide
Standard C++ does not support variable length arrays. Some implementations provide it as an extension but as you have already found out, relying on them makes for non-portable code.
I recommend you use a std::vector instead. It works with pure standard C++.
int size;
if (!(std::cin >> size) || (size < 0))
throw std::invalid_argument {"bad size"};
std::vector<int> numbers (size);
In GCC and Clang, you can use the -pedantic compiler switch to turn off any non-standard extensions. This will help you avoid accidentally writing non-portable code. Of course, you should also compile with -Wall, -Wextra and -Werror.

Some codes are not running properly in DEV C++

I have been using DEV C++ for the last 2 months and never faced such an issue. But today when I am running the follow code, the execution screen is displaying nothing.
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cout<<"ENTER THE LENGTH OF THE ARRAY:";
cin>>n;
int a[n];
cout<<"ENTER THE ELEMENTS OF THE ARRAY:";
for(int i=0; i<n; i++){
cin>>a[i];
}
const int N = 1e6+2;
int idx[N];
for(int i=0;i<N;i++){
idx[i]=-1;
}
int minidx = INT_MAX;
for(int i=0; i<n; i++){
if(idx[a[i]]!=-1){
minidx = min(minidx, idx[a[i]]);
}
else{
idx[a[i]]=i;
}
}
if(minidx == INT_MAX){
cout<<"NO REPEATING ELEMENT FOUND";
}
else{
cout<<"REPEATING ELEMENT FOUND AT:"<<minidx+1;
}
return 0;
}
This is the screenshot of the output screen.
Pls suggest me a solution to this problem.
I have been using DEV C++ for the last 2 months
Notice that DEV C++ is an old, non-standard conforming, and buggy compiler.
int n;
cout<<"ENTER THE LENGTH OF THE ARRAY:";
cin>>n;
int a[n];
What would happen if your user has input -1234? Arrays cannot have negative dimensions, and your code did not test that!
You deserve using a better C++ compiler
E.g. the ones (GCC or Clang) inside a Debian distribution, with a good source code editor such as GNU emacs and some good build automation tool like GNU make.
#include <bits/stdc++.h>
is wrong and non standard conforming, and is slowing down your compilation.
const int N = 1e6+2;
int idx[N];
This is not reasonable: you want more than four millions bytes on your call stack, which is often limited to a megabyte. My guess is that you are experimenting some stack overflow for your automatic variable idx
Consider using standard C++ containers, and upgrade your compiler to a decent one.
I recommend using a recent GCC (at end of 2020, this means GCC 10) compiler as g++ -Wall -Wextra -g since you want all warnings and debug info. You could even use static analysis options to g++
Once you got no warnings, use the GDB debugger to understand the behavior of your program.
Read a good C++ programming book
See this C++ reference, the documentation of your C++ compiler, and of your debugger.
Consider using tools like the Clang static analyzer on your code.
Refer to a recent C++ draft standard, such as n4659. Be afraid of undefined behavior. Take inspiration from existing C++ open source code on github or gitlab.
In a few months, if so allowed, consider coding your GCC plugin to find some bugs in your programs. Be aware of Rice's theorem.
DevC++ seems now supported by Embarcadero: https://github.com/Embarcadero/Dev-Cpp/releases checked it, and it is looking ok enough. I will assume that you are not using the 1991 version of this IDE and the compiler it came with; Of course, if you want to use it with Windows 98 then the old version might be an option,
Anyhow, I will try to list the issues in your code. Most of them are a trap for beginners:
int n;
cout<<"ENTER THE LENGTH OF THE ARRAY:";
cin>>n;
in this part, you are not forcing flushing before asking for user input. It is always a good practice to flush before user-input. How this can be an issue? Long story short you can get for example C/C++ printf() before scanf() issue
solution: c++ force std::cout flush (print to screen).
Let's continue you are using Variable-length array (VLA) here which is not supported by C++ stdandard,
int a[n];
You can check for more Why aren't variable-length arrays part of the C++ standard?
Recommend using std::vector a(n); there which it will allocate in the heap. If yo want the allocation in the stack, within standards then you either need to wait for "dynarray" (which may never be available in C++) or switch to C...
const int N = 1e6+2;
int idx[N];
for(int i=0;i<N;i++){
idx[i]=-1;
}
in the code below, you are trying to allocate a gigabyte of buffer in the stack. I suspect this is the reason why your program is not running properly. If you want a cheap hack then you can convert this allocation to "static int idx[N];" which will move this buffer to the heap. Beware using a static variable is not a good practice at all and not recommending it. Recommend either "new []" or "vector" there too,
for(int i=0; i<n; i++){
if(idx[a[i]]!=-1){
minidx = min(minidx, idx[a[i]]);
}
else{
idx[a[i]]=i;
}
}
idx[a[i]] has no boundary check. you should check the boundary for both arrays.
First of all, this is a security leak and a very bad-way of writing a program: Example of a buffer overflow leading to a security leak
Also, this part looks like it has a logic issue: Withing the boundary all the "idx" elements should be "-1" so you should never get into the else-condition (in a normal way)

What are different ways of initializing the size of an array with user input in c++

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).

Basic creation set in c++

I have tried to realize set by basic metods via struct.
This is my variant:
#include <iostream>
using namespace std;
struct Set<T> {
int n;
T[n] elements;
}
int main(){
struct Set microSet;
int oneElm, length;
cin>>length;
microSet.n=length;
for(int i=0;i<length;i++) {
cin>>oneElm;
microSet.elements[i]=oneElm;
}
for(int i=0;i<length;i++)
cout << microSet.elements[i];
return 0;
}
Compilator shows me an error related with sruct.
What've I done wrong?
Your code is illegal (and wrong in many places, so take a few days to read a good C++ book then look at some C++ reference website). You can't declare a variable length array as a member of a struct or class (and even if you could, you have the wrong syntax; some compilers support them as an extension, and C99 -but no C++ dialect- has flexible array members).
You'll better use existing standard C++ containers. If you can't use them, you need pointers (and you should prefer smart pointers).
Even if you have some compiler accepting VLAs as an extension, you probably need to dynamically allocate a memory zone for them.
I strongly recommend learning to use containers.
Don't forget to enable all warnings & debug info when compiling. With GCC, compile with g++ -Wall -Wextra -g. Use the debugger (gdb) and perhaps valgrind.