I am new to C++. Below is code to input and display an array -- a simple thing to understand how things work.
int main() {
int N, i;
int A[N];
cin >> N;
for (i = 0; i < N; i++) {
cin >> A[i];
}
for (i = 0; i < N; i++) {
cout << A[i];
}
return 0;
}
The input is:
4
1 2 3 4
and output is:
12
I have corrected my code to:
int N, i;
cin >> N;
int A[N];
This correctly displays the array.
What exactly happened? Should N have a value before initializing A[N]? But then why didn't my initial code work? Is this something to do with Hierarchy? If so, how can I get my priorities right?
If N is initialized as a large value, N has an input of specific number next, if so how come even if N=9, the output remains same: 12?
Should N have a value before initializing A[N]
Yes. It should. It should even have a value before declaring A[N].
How else would the runtime know how much space to allocate for A?
To answer your question.
int N, i;
Here, you declare N, but because you don't assign a value to N, N is uninitialized and can hold any value (probably some old program's value.)
And you create an array with N, which will lead to some unexpected behavior. (for example, a stack overflow could happen when N is too big)
And:
The size of arrays in C++ has to be known at compile-time. That means when you compiler compiles the program, the array's size has to be known.
In your case, you know n (the size) at runtime, which means only when you run the program, you know the value of n, which is the size.
Your code run because (probably) gcc compiler does have an extension for this to happen, but because this is not standard C++, I would recommend not using it.
C++ has a solution for runtime array, and that is std::vector in the <vector> header.
You just need to change:
cin >> N;
int A[N];
to:
std::cin >> n;
std::vector<int> A(N);
note: using namespace std; is bad, so don't use it.
In C++, the size of an array must be a compile time constant. So the following code is incorrect:
int N = 10;
int arr[N]; //incorrect
The correct way to write this would be:
const int N = 10;
int arr[N]; //correct
For the same reason the following code is incorrect in your given code snippet:
int N, i; //both N and i are **unitialized**(meaning they have **garbage value**)
cin >> N; //this is fine. This takes input from user and put it in N
int A[N]; //incorrect because N must be a constant expression
Also note that your original question used the garbage value of N to create an array. This is why it is advised that always initialize built in type in block/local scope.
Related
I have no idea why, but my code just stops at the 2nd for loop in the cin line, if it loops more than 1 time.
Can you help me?
This is my code:
#include <iostream>//Julianne
using namespace std;
int main(){
int a;
cin >> a;
int bezorgen[a];
int afhalen[a];
for (int i = 0; i < a; i++){
cin >> bezorgen[i];
}
for (int j = 0; j < a; j++){
cin >> afhalen[j];
}
return 0;
}
P.S. Sorry for my grammar mistakes.
C++'s declaration
int name[N] is only valid when N is constant. For dynamic sized array (which is in your case dynamic, cause array size comes from user input) you can use:
C++ std::vector<int>
int *name = new int[a]
First one is the list, not an array. So you need to .push_back elements before they can be accesed.
Second one is an array, and accessed just like common array. Be careful with that, because you need to free memory when it's not needed anymore, call delete [] name; at the end of your program for every new type[size] you've done.
Currently, C++ only allows declaring arrays with length as integers. Is there any way to get around it? I am trying to create a program that generates an array that can potentially reach thousands or even millions in length depending on input, but array declaration limiting to integer-only length is holding me back.
Comment Basically, supposing that I want to create a 2d array with 5 rows and 500,000 columns, I get a segmentation fault.
The prototype for std::array is
template<class T, std::size_t N> struct array;
According to https://en.cppreference.com/w/cpp/types/size_t,
std::size_t can store the maximum size of a theoretically possible
object of any type (including array). A type whose size cannot be
represented by std::size_t is ill-formed (since C++14)
(emphasis mine)
So C++, by definition, cannot express the concept of an object whose size is larger than a std::size_t.
Fortunately, on most platforms std::size_t is going to be 32 bits at a minimum, meaning it can reach not only millions but billions. And if you're on a platform where it's smaller than that then presumably your hardware isn't physically capable of storing larger objects anyway.
UPDATE: In the comments you add
Sorry, I ought to have been more specific. Basically, supposing that I
want to create a 2d array with 5 rows and 500,000 columns, I get a
segmentation fault.
If the problem here were a limitation of the language, you would get a compiler error, not a runtime error.
Since you're getting a runtime error, the problem is with your platform, not the language. In this particular case, the "problem" is that it doesn't give you enough stack space to support multi-megabyte objects in a stack frame. (This is a pretty sensible limitation, if you ask me.) Instead, you'll want to allocate your data on the heap.
I could hand you some code that would just make your problem go away for now, but what you really need to do is read about the stack and heap and understand what they are and how to use them.
#include <iostream>
int main() {
int n = 0;
std::cin >> n;
int *arr = new int[n]; // dynamic declaration of variable length array
for(int i = 0; i < n; ++i)
std::cin >> arr[i]; // read array elements
return 0;
}
EDIT: For 2d array
#include <iostream>
int main() {
int **arr;
int r, c;
std::cin >> r >> c;
// Create an array of row heads
arr = new int *[r];
// Create an 2d array
for (int i = 0; i < r; ++i) arr[i] = new int[c];
// read input in 2d array
for (int i = 0; i < r; ++i)
for (int j = 0; j < c; ++j) std::cin >> arr[i][j];
// print 2d array
for (int i = 0; i < r; ++i)
for (int j = 0; j < c; ++j) std::cout << arr[i][j] << ' ';
return 0;
}
std::vectoris a better choice. You only need push_back or emplace_backto add element into it.
More details:
http://www.cplusplus.com/reference/vector/vector/
I am just trying to initialize a huge array. My code is given below:
#include<iostream>
using namespace std;
int main()
{
int T;
cin >> T;
while (T--)
{
int d;
cin >> d;
int arr[d + 1];
for (int i = 0; i <= d; i++)
arr[i] = 0;
}
return 0;
}
Now when I input
1 502334160
then I got error Runtime Error - SIGSEGV.
I want to know how to initialize this type of array.
The array may be too big to fit in your program's stack address space. If you allocate the array on the heap you should be fine.
int* arr = new int[d + 1];
But remember that this will require you to delete[] the array. A better solution would be to use std::vector<int> and resize it to d + 1 elements.
First: Variable length arrays (VLA) are illegal in C++. It might be an extension (as it is in gcc), but it won't build on all compilers.
Second: You can initialize an array with brace initialization. If you don't specify all elements, the others will get default value of 0 (in case of int). So:
int arr[SIZE] {} //specify 0 elements -> all initialized to value 0
Third thing: you allocate your array on stack, so when you create an array of length 1502334160 than it's stack overflow. This amount of ints (assuming 4 bytes each) is almost 6GB of memory while stack is usually 1-2MB.
This question already has answers here:
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 5 years ago.
I made a code in which I had to take the size of an array as the user’s input and its elements too and print them.
#include <iostream>
using namespace std;
//Compiler version g++ 6.3.0
int main()
{
int i;
cout<<"\nenter the size of array";
cin>>i;
int n[i];
for(int j=0;j<=i;j++)
{
cout<<"\nn["<<j<<"]=";
cin>>n[j];
}
for(int k=0;k<=i;k++)
{
cout<<endl;
cout<<"\nn["<<k<<"]=";
cout<<n[k];
}
}
Suppose in the following:
The value of i is 3 (according to user’s input).
In the first loop the condition for j is up to <=i where i is the size of array (this shouldn't happen as i begins from 0) due to which the Compiler asks me to input 4 values for the array (n[0], n[1], n[2] and n[3]) but the size of the array is 3 only. How can it store 4 objects?
Change this:
for(int j=0;j<=i;j++)
to this:
for(int j = 0; j < i ; j++)
since array indexing ends at the size of the array minus 1. In your case i - 1.
Likewise, you neeed for(int k=0;k<i;k++).
Your posted code invoked Undefined Behavior, by accessing the array out of bounds.
This:
int n[i];
is a Variable Length Array (VLA), which is not Standard C++, but is supported by some extensions.
and if you compiled with pedantic flag, you would get:
prog.cc: In function 'int main()':
prog.cc:9:9: warning: ISO C++ forbids variable length array 'n' [-Wvla]
int n[i];
^
If you want something like this data structure, then I suggest you use an std::vector instead, which is Standard C++.
By the way, it's not a syntax error or something, but i is usually used as a counter (like you used j), an index if you like. As a result, I would chnage it's name to size, for instance, or something related.
EDIT:
Example with std::vector and variable renaming:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int tmp, n;
cout<<"Input number of elements\n";
cin >> n;
vector<int> v;
for(int i = 0; i < n; ++i)
{
cin >> tmp;
v.push_back(tmp);
}
for(auto number: v)
cout << number << endl;
return 0;
}
You need to check for less than i and not less than equal i. Otherwise it will try to store value for 0,1,2,3 in that case the last object will cause memory corruption. In c++ it will not give you any error even if you try to add 100 members in array of size 3.
It better you read memory management in c++ before jumping into coding.
I have created a struct in C++ of the following type:
struct longsir {
int len;
long *sir;
int isinitialised;};
Now, I have to modify the length of a structure, for which I used the following function:
longsir modlen(longsir *s, int newlen){
if (s ->isinitialised ==1 && newlen != s->len) {
if (newlen < s-> len) {
longsir a;
a.len=newlen;
a.isinitialised=1;
a.sir=new long[a.len];
int i;
for (i=0;i<newlen;i++){
a.sir[i]=s->sir[i];};
return a;}
else {
longsir a;
int i; int oldlen=s->len;
a.len=newlen;
a.isinitialised=1;
a.sir=new long[a.len];
for (i=0;i<(s->len);i++){
a.sir[i]=s->sir[i];};
cout <<"Introduceti restul elementelor din sir ";
//Code works till here
for(i=oldlen;i>newlen;i++){
cout <<"Introduceti elementele sirului cu numarul "<<i<<endl;
cin.clear();
cin >> a.sir[i];}
return a;}}}
So, when I choose to use a value bigger than the initial length of the initial array, the code at first creates a new array, after that copies the data from the old array and asks the user to fill in the remaining cells from stdin. Anyway, when running the program, it only asks for introduction of the remaining elements, and after that automatically initialises them to 0. Why is it that the code doesn't work as suggested? I can't find any clue about this situation. Thank you very much for your help.
P.S. You can see the entire original code on Pastebin: the main function and the header file
for(i=oldlen;i>newlen;i++){ maybe i < newlen
for(i=oldlen;i>newlen;i++) there have to be i < newlen I think.