array declaration in runtime and compile time - c++

Please look at the following 2 program segments:
int a,b;
cin>>a>>b;
int arr1[a*b];
int arr2[a];
now if i give input value of 'a' = 100000 and 'b' = 5, program shows runtime error because of memory overflow I think. Now look to the other segment of code:
int arr1[500000];
int arr2[100000];
Now when I declare array of same size as shown in above code, The program works fine. Why is that so?

Now when I declare array in advance of same size I declared at runtime, The program works fine. Why is that so?
Because variable length arrays (aka VLAs) aren't valid standard c++ code.
If you need such thing allocated at runtime the idiomatic c++ way is to use a std::vector:
int a,b;
cin>>a>>b;
std::vector<int> arr1(a*b);
std::vector<int> arr2(a);

Related

Why should global array size be an integer constant?

In C++ I tried declaring a global array of some size. I got the error:
array bound is not an integer constant before ‘]’ token
But when I declared an array of the same type in the main() function it is working fine.
Why is there different behaviour here?
int y=5;
int arr[y]; //When I comment this line it works fine
int main()
{
int x=5;
int arr2[x]; // This line doesn't show any error.
}
Edit: Many are suggesting this question is a duplicate of Getting error "array bound is not an integer constant before ']' token". But that question doesn't answer why there is different behaviour.
Both examples are ill-formed in C++. If a compiler does not diagnose the latter, then it does not conform to the standard.
Why there is a different behaviour here?
You use a language extension that allows runtime length automatic arrays. But does not allow runtime length static arrays. Global arrays have static storage.
In case you are using GCC, you can ask it to conform to the standard by using the -pedantic command line option. It is a good idea to do so in order to be informed about portability problems.
The size of an array must be a constant. You can fix this by declaring y as const.
const int y=5;
int arr[y];
As for why this worked in main, g++ does allow a variable length array in block scope as an extension. It is not standard C++ however.
Both shouldn't be used, one works because (as #eerorika said) automatic length arrays are allowed on runtime, but global arrays need to have static storage.
If you want to declare an array with a variable size (e.g. given by std::cin) you would do something along the lines of:
int x;
std::cin >> x;
const int n = x;
float arr[n];
But you wouldn't be able to set it to contain just zeros with float arr[n] = {0} (if you need to add to a value in the array, not being sure you set it), you would need to use a loop like that
for(int i = 0; i < n; i++)
{
arr[i] = 0;
}
The type-system of C++ handles these C-like arrays in a way that it defines arr2 from your example of type int[5]. So, yes the number of elements of the array is part of the type!
This puts some constraints on what you are allowed to use in the definition of C-like arrays. I.e. this number needs to have static storage, needs to be immutable and needs to be available at compile time.
So, you might want to change your code to something like the following, which will have another goodie. It initializes the array in a proper way:
int arr2[] = {0, 0, 0, 0, 0};

Why I am getting garbage(unwanted) output here?

Whenever I am writing this following code, I am getting garbage(unexpected) output in some online compiler, but if I use code block then getting satisfied output. So my question is why I am getting this type of output?
for example, if I input
5 7
+ 5
- 10
- 20
+ 40
- 20
then I am getting
22 1
in the code block. But in the online compiler, it's something else.
#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
int have, n, i;
int kid=0;
cin>>n>>have;
int line[n];
for(i=0;i<n;i++)
{
cin>>line[i];
if(line[i]>=0)
have+=line[i];
else
{
if(have>=abs(line[i]))
have+=line[i];
else
kid++;
}
}
cout<<have<<" "<<kid<<endl;
}
The main problem I can see in your code is this:
int line[n];
This is known as a VLA (Variable Length Array) and it is not supported in C++. It is valid in C. Most compilers still allow this behaviour due to the fact that C++ is based on C, but it is not valid C++ code. In a previous question, I found out that clang supports designated initializers, when gcc and vc++ did not. The reason is because some compilers like clang, support c99-extensions by default. My point is that just because the code compiles, it doesn't mean it's always right.
If you compile with the -pedantic argument, you will see that the compiler is warning you about this being a C99 feature. Have a look at the rextester example here. From the comments below, using -pedantic-errors in the compiler flags, will prompt an error.
If you know the size of the array before run-time, then you should use a static array int line[4];, but if you don't then you need to use a dynamic array. std::vector is essentially a dynamic array that also handles memory for you. It's easy to use and very efficient. std::vector<int> line;
You can read more about the vector container here: http://www.cplusplus.com/reference/vector/vector/
Btw, I tried your code in rextester, ideone and repl.it and I got the same results: 22 1. I think what you are witnessing it undefined behaviour.
Also, you can qualify int n with constexpr and it'll be fine.
constexr int n = 200;
int line[n]; //now it's ok.
But this again means that you know the size of the array at compile time.

Implicit array sizing and crash c++

I tried to declare and initialize the array like this int a[]={},but the program crashed.
#include<iostream>
using namespace std;
void test(int b []){
for(int i=0;i<9;i++)
b[i]=i+1;
}
int main()
{
int a[]={};
test(a);
for(int i=0;i<9;i++)
cout<<a[i]<<endl;
}
The output on the console before it crashed is as follow:
0
2
3
4
5
6
7
8
9
But the program does what it suppose to be when I declared the array with size(int a[9]={}).Can someone tell me what's the reason behind?Thank you.
This code is ill-formed. See C++14 [dcl.init]/4:
An empty initializer list {} shall not be used as the initializer-clause for an array of unknown bound.
The compiler could reject the code, and if it doesn't then the behaviour of the program is completely undefined by the C++ standard. Some compilers have a non-standard extension allowing zero-sized arrays.
Do you mean to use dynamic allocation?
This means you declare an array but don't give it a fixed size.
int size = 10;
int * arr = new int[size];
Now you can add things to arr[] like normal. If you need more space, you have to make another array of the new size, copy the values over, set the new array equal to the old one (arr = newArr), then IMPORTANT: do delete [] newArr;
This is because arrays do not handle memory allocation by themselves like vectors do. You have to give it a number for the size, or declare it dynamically.

Defining Array C/C++

What is the difference between this two array definitions and which one is more correct and why?
#include <stdio.h>
#define SIZE 20
int main() {
// definition method 1:
int a[SIZE];
// end definition method 1.
// defintion method 2:
int n;
scanf("%d", &n);
int b[n];
// end definition method 2.
return 0;
}
I know if we read size, variable n, from stdin, it's more correct to define our (block of memory we'll be using) array as a pointer and use stdlib.h and array = malloc(n * sizeof(int)), rather than decalring it as int array[n], but again why?
It's not "more correct" or "less correct". It either is xor isn't correct. In particular, this works in C, but not in C++.
You are declaring dynamic arrays. Better way to declare Dynamic arrays as
int *arr; // int * type is just for simplicity
arr = malloc(n*sizeof(int*));
this is because variable length arrays are only allowed in C99 and you can't use this in c89/90.
In (pre-C99) C and C++, all types are statically sized. This means that arrays must be declared with a size that is both constant and known to the compiler.
Now, many C++ compilers offer dynamically sized arrays as a nonstandard extension, and C99 explicitly permits them. So int b[n] will most likely work if you try it. But in some cases, it will not, and the compiler is not wrong in those cases.
If you know SIZE at compile-time:
int ar[SIZE];
If you don't:
std::vector<int> ar;
I don't want to see malloc anywhere in your C++ code. However, you are fundamentally correct and for C that's just what you'd do:
int* ptr = malloc(sizeof(int) * SIZE);
/* ... */
free(ptr);
Variable-length arrays are a GCC extension that allow you to do:
int ar[n];
but I've had issues where VLAs were disabled but GCC didn't successfully detect that I was trying to use them. Chaos ensues. Just avoid it.
Q1 : First definition is the static array declaration. Perfectly correct.
It is when you have the size known, so no comparison with VLA or malloc().
Q2 : Which is better when taking size as an input from the user : VLA or malloc .
VLA : They are limited by the environment's bounds on the size of automatic
allocation. And automatic variables are usually allocated on the stack which is relatively
small.The limitation is platform specific.Also, this is in c99 and above only.Some ease of use while declaring multidimensional arrays is obtained by VLA.
Malloc : Allocates from the heap.So, for large size is definitely better.For, multidimensional arrays pointers are involved so a bit complex implementataion.
Check http://bytes.com/topic/c/answers/578354-vla-feature-c99-vs-malloc
I think that metod1 could be little bit faster, but both of them are correct in C.
In C++ first will work, but if you want to use a second you should use:
int size = 5;
int * array = new int[size];
and remember to delete it:
delete [] array;
I think it gives you more option to use while coding.
If you use malloc or other dynamic allocation to get a pointer. You will use like p+n..., but if you use array, you could use array[n]. Also, while define pointer, you need to free it; but array does not need to free.
And in C++, we could define user-defined class to do such things, and in STL, there is std::vector which do the array-things, and much more.
Both are correct. the declaration you use depends on your code.
The first declaration i.e. int a[size]; creates an array with a fixed size of 20 elements.
It is helpful when you know the exact size of the array that will be used in the code. for example, you are generating
table of a number n up till its 20th multiple.
The second declaration allows you to make an array of the size that you desire.
It is helpful when you will need an array of different sizes, each time the code is executed for example, you want to generate the fibonacci series till n. In that case, the size of the array must be n for each value of n. So say you have n = 5, in this case int a [20] will waste memory because only the first five slots will be used for the fibonacci series and the rest will be empty. Similarly if n = 25 then your array int a[20] will become too small.
The difference if you define array using malloc is that, you can pass the size of array dynamically i.e at run time. You input a value your program has during run time.
One more difference is that arrays created using malloc are allocated space on heap. So they are preserved across function calls unlike static arrays.
example-
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n;
int *a;
scanf("%d",&n);
a=(int *)malloc(n*sizeof(int));
return 0;
}

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