Some codes are not running properly in DEV C++ - 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)

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.

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.

Can we create variable length arrays in 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.

why cpp allows to get a access to memory i haven't allocated?

In cpp one can use an array declaration as
typename array[size];
or
typename *array = new typename[size];
Where array is of length 'size' and elements are indexed from '0' to 'size -1'
Here my question is am I allowed to access the elements beyond the index >= size.
So I wrote this little code to check it
#include <iostream>
using namespace std;
int main()
{
//int *c; //for dynamic allocation
int n; //length of the array c
cin>>n; //getting the length
//c = new int[n]; //for dynamic allocation
int c[n]; //for static allocation
for(int i=0; i<n; i++) //getting the elements
cin>>c[i];
for(int i=0; i<n+10; i++) //showing the elements, I have add up 10
cout<<c[i]<<" "; //with size to access the memory I haven't
//allocated for
return 0;
}
And the result is like this
2
1 2
1 2 2686612 1970422009 7081064 4199040 2686592 0 1 1970387429 1971087432 2686700
Shouldn't the program crashed but gives garbage values. And for both the allocation methods it gives the same result. It makes more bugs which are hard to detect. Is it related with the environment or the compiler I am using or anything else?
I was using codeblocks IDE having TDM-GCC 4.8.1 compiler on windows 8.1
Thanks in advance.
This is called "undefined behavior" in the C++ standard.
Undefined behavior can mean any one of the following:
The program crashes
The program continues to run, but produces meaningless, garbage results
The program continues to run, and automatically copies the entire contents of your hard drive, and posts it on Facebook
The program continues to run, and automatically subscribes you to Publishers Clearinghouse Sweepstakes
The program continues to run, but your computer catches fire and explodes
The program continues to run, and makes your computer self-aware, which automatically links and networks with other self-aware networks, forming Skynet, and destroying the human race
Conclusion: do not run and access elements past the end of your arrays.
The c++ compilers don't enforce this as there is no specification to do so.
When you access an element of an array there is no boundary check done. c[i] just gets translated to c + i * sizeof(int) and that's it. If that area of memory is not initialize you'll get garbage, but you could be getting other useful information it all depends on what is there.
Please note that depending on the OS and the c++ runtime you're running you can get different results, for instance on a linux box you'll probably be getting a segmentation fault and the program will crash.