Array size in C++ [duplicate] - c++

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.

Related

Beginner C++ Array

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.

Does arr[n] prints the length of the array in C++?

#include <bits/stdc++.h>
using namespace std;
int main()
{
int arr[4]={1,2,3,4};
for(int i=0; i<6; i++){
cout << arr[i]<<endl;
}
return 0;
}
I tried running this code in visual studio and I'm getting the output as:
1
2
3
4
4
4200976
After modifying it also, I'm getting arr[n] as the length of the array.
So is it always true, and can we assume that it is the most optimised way to get the length of the array?
The behavior of accessing elements outside the bounds of the array is undefined.
and can we assume that it is the most optimised way to get the length of the array?
This isn't a way to get the length of the array.
A correct, and efficient way to get the size of the array is to use std::size(arr).

segmentation fault in pointers while handling arrays

I am trying to multiply array elements with 5 but I am getting the error of core dumped and if not, then, it only multiplies 5 with first element.
Here the code:
#include <iostream>
using namespace std;
int ptr_multiply(int[],int);
int main(){
int size;
cout<<"Enter the size of an array ==";
cin>>size;
int arr[size];
cout<<"Enter the elements of array ==";
for (int i=0;i<size;i++){
cin>>arr[i];
}
ptr_multiply(arr,size);
}
int ptr_multiply(int a1[],int s1){
int *ptr;
for (int i=0;s1;i++)
{
*ptr=a1[i];
ptr*=5;
cout<<"The Elements"<<" "<< i <<" "<<" after multiplying 5 is =="<<*ptr;
}}
*ptr=a1[i];
ptr*=5;
First line: You dereference a pointer that points nowhere (it is uninitialized). That is wrong and causes undefined behavior. You try to assign to an int when there is no int.
Second line: You do not dereference the pointer. You multiply the value of the pointer by 5 when you actually want to multiply the int it points to by 5 (remember: there is no int it points to).
You do not need a pointer here:
for (int i=0;i < s1;i++) {
int value = a1[i];
value *= 5;
cout<<"The Elements"<<" "<< i <<" "<<" after multiplying 5 is =="<<value;
}
Also the condition was wrong. It should be i < s1.
Last but not least, dont use C-arrays in C++. They are difficult to use and error-prone. Prefer std::array for fixed size arrays and std::vector for dynamic size. Actually int arr[size]; is not standard C++, see Why aren't variable-length arrays part of the C++ standard?

linker error in C++ (again) [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
so I needing some help with creating a program for my class. The lab requires us to use pointers.
This is the description of what we have to do...
-Write a function that accepts an int array and the array's size as arguments.
-The program should ask the size of the array and lets the users enter some integer values.
-The function should create a new array that is one element larger than the argument array.
-The first element of the array should be set to 0.
-Element 0 of the argument array should be copied to element 1 of the new array.
-Element 1 of the argument array should be copied to element 2 of the new array, etc.
-The function should return a pointer to the new array.
-There should be three other functions: getMode, getMedian and getAverage.
-These functions should get Mode, Median and Average of the values within an array.
-You should display the argument array and the new array as well as the mode, median and the average.
This is what I have so far I'm not sure if its right. Any help is greatly appreciated.
UPDATE: I run the program and it asks the user for the size of the array and the values for it...
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <string>
int* addToSize (int*, int);
using namespace std;
int main()
{
int userSize=0; //Holds user size
int userInts; //Holds uaer values
int *memory; //dynamically allocate an array
//int *intptr;
//int *arrayNew;
//int newA;
//Gets array size
cout << "Please enter the array size!" << endl;
cin >> userSize;
//Memory array
memory = new int [userSize];
//Grab values for the amount of user size
for (int count = 0; count < userSize; count ++)
{
cout << "Please enter the value for " << count+1 << endl;
cin >> userInts;
}
for (int index = 0; index < userSize; index ++)
{
cin >> memory[index];
}
//Sets addToSize function to memory array
memory = addToSize(memory, userSize);
//Shows memory array
for(int index=0;index< (userSize + 1);index++)
cout<<memory[index]<<endl;
delete[] memory; //Used to delete memory array
memory = 0; //sets memory array to 0
return 0;
}
int* addToSize(int* arrayNew, int newSize)
{
int* expandSize= new int [newSize +1];
for (int index = 0; index < newSize; index++)
{
expandSize[index]= arrayNew[index];
}
for (int index = newSize; index < (newSize+1); index ++)
{
expandSize[index]=0;
}
return expandSize;
}
You have declared a forward reference to some addToSize() function which accepts 2 arguments, and you proceed to invoke it from within your main(), and that's all very fine and dandy, but then further down you define an addToSize() which accepts 3 arguments.
So, what is happening is that the declared function is unrelated to the defined function. The compiler completely ignores the 3-argument function, since you are not calling it, and it assumes that you will provide a definition for the two-parameter function in some other source file.
But then when the linker attempts to link your program, there is no other file containing an addToSize() with two arguments, so the linker fails with an error message which describes precisely what happened. (It is a linker error. It has nothing to do with pointers and arrays.)
Hint: before fixing your function definition to match the declaration, lose the forward declaration, move the function to the start of the file, and make it static.

If we declare an array of four elements, can these elements store values?

In C++ if we declare an array of four elements, can these elements store values? I mean, if we declare the following array:
#include <iostream>
int main()
{
int a[4];
double res;
double avg;
avg = res = 0.0;
for(int i=0; i<4; i++)
{
cout<<"Please enter age ";
cin>> a[i];
}
for(int i=0; i<4; i++)
{
cout<< "You have entered these ages " <<a[i];
cout<<endl;
res += a[i];
}
avg = res/4;
cout<< "Total is "<<res <<endl;
cout<< "Avg is "<<avg;
}
this above program is a program with an integer (numeric) array, while in character array can we assign any value of the character array's elements?
Yes.
Array is a placeholder for the values of same type and no. of places are reserved during array declarion.
int a[3];
means it can store 3 ints. to be accessed as a[0], a[1] and a[2].
Now, you can see the problem you have in your loop:
for(int i=1; i<=4; i++)
{
cout<<"Please enter age ";
cin>> a[i];
}
a[0] remains empty
loop runs 4 times: a[1], a[2], a[3], a[4] and, last 2 indices are not reserved.
You can correct it as following:
for(int i=0; i<3; i++)
{
cout<<"Please enter age ";
cin>> a[i];
}
your other question:
while in character array can we assign any value of the character array's elements
Nope, Each index will store exactly one char.
char c[3];
will store exactly 3 chars. if you tried to use other indices it may result into undefined behaviour, segmentation fault. as you are trying to access memory that was not allocated to your process.
Yes, the declared elements are available to store values.
However, in your example you have only declared a 3-element array, which gives you array elements a[0], a[1], and a[2]. You are accessing array elements a[1], a[2], a[3], a[4], resulting in an out-of-bounds situation.
If you are asking whether it's possible to assign a value to an element of an array, then the answer is yes. All of the following is perfectly valid:
char a[10];
a[4] = 'x';
std::cin >> a[6];
Note however that your code contains errors:
You index a with indices 1 to 4. This means a must be at least 5 elements long; it's currently defined with length of 3.
#include <iostream.h> should be just #include <iostream>. <iostream.h> is pre-standard and obsolete.
C++ array indices are 0 based, so while not technically an error, you're ignoring the first element of your array. You should probably phrase your for loops as for (int i = 0; i < 4; ++i)