Array size declarator, can they be calculated? VC++ - c++

Ubernoob question:
Is it possible in MS Visual C++ to declare an array size based upon user input?
int userNum;
cin >> userNum;
const int SIZE = userNum;
int myArray[SIZE];
It seems that if I use a variable in any way to initialize the constant SIZE, that VC++ no longer sees it as a constant for the purposes of setting the array size.
Is there a way around this?

This can be done usign a std::vector
#include <iostream>
#include <vector>
int main() {
int userNum;
std::cin >> userNum;
std::vector<int> myArray(userNum);
myArray[1]=42;
return 0;
}
Note this example has no checks for the size the user has entered.

Using C-style arrays is a bad idea.
Prefer std::vector.
std::vector<int> vec(5); // Vector of 5 ints

No way ;-), you have to allocate the memory dynamically. There are many ways to do that (I'm proposing 3 different solutions here):
int userNum;
cin >> userNum;
const int SIZE = userNum;
int* myArray1 = new int[SIZE];
int* myArray2 = (int*) malloc( sizeof(int) * SIZE ); // not 100% sure about the syntax
// or, better, because memory will be released automatically for you:
std::vector<int> myArray3( SIZE ); // Thank you crashmstr for the comment
And later, when you are done, you'll have to release it:
delete [] myArray1;
free( myArray2 );
// no need to free myArray3
// Note that statically allocated memory (int myArray[SIZE]) is automatically released
myArray[SIZE] is a static allocation done at compilation time, it cannot be controlled by a user input (except if the user is the programmer....who can change the size before the program is actually compiled ;-)
Proposed solution are using dynamic allocation done at runtime, it can be controlled by a user input.

Above mentioned answers about std::vector are absolutely correct.
But if you want to resize the your vector based on user input, you can do:
#include <vector>
std::vector<int> vec;
std::cin >> userSize;
vec.resize(userSize);

Related

Normal array declaration vs. dynamic array declaration

I just started learning C++. I learned the easy way of declaring arrays and now I'm confused about the usage of
int* foo = new int[n];
and how it is different from
int foo [n];
I tried testing with code but couldn't find any difference. I read from sources that using "new" requires me to manually de-allocate the memory after I don't need it anymore. In that case, there is no advantage in using "new" or dynamic memory allocation at all. Am I missing something here?
I tried running this:
#include <iostream>
int main() {
int n;
std::cout << "array size" ;
std::cin >> n ;
std::cout << n ;
int foo [n]; //line A
// int* foo = new int[n]; //line B
foo[6] = 30;
std::cout<<foo[6]<<std::endl;
}
Commenting out line B to run line A, or vice versa, gave the exact same result.
There are several ways these are different. First, let's talk about this one:
int n = 10;
int array[n];
This is not part of the ANSI C++ standard and may not be supported by all compilers. You shouldn't count on it. Imagine this code:
int n = 10;
int array[n];
n = 20;
How big is array?
Now, this is the way you can do it (but it's still problematic):
int n = 10;
int * array = new int[n];
Now, that is legal. But you have to remember later to:
delete [] array;
array = nullptr;
Now, there are two other differences. The first one allocates space on the stack. The second allocates space on the heap, and it's persistent until you delete it (give it back). So the second one could return the array from a function, but the first one can't, as it disappears when the function exits.
HOWEVER... You are strongly, strongly discouraged from doing either. You should instead use a container class.
#include <array>
std::array<int, n> array;
The advantages of this:
It's standard and you can count on it
You don't have to remember to free it
It gives you range checking

How to make the array size correct in C++?

I'm trying to create an array and the size of the array depends on the user input. But there is an error in my code, It said: "expression must have a constant value".
Here is my code:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int var;
cout << "What size do you want to choose: "<< endl;
cin >> var;
int arr[var];
}
How can I change my code and make it work?
How can I change my code and make it work?
Change
int arr[var];
to
std::vector<int> arr(var);
This will require #include <vector>
The syntax you are using is known as a "variable length array", and is NON-STANDARD. Only a few compilers support it as an vendor-specific extension to the C++ language.
A standard compliant fixed-length array must have its size known to the compiler as a compile-time constant.
For what you want, you need to use the new[] operator instead:
int *arr = new int[var];
...
delete[] arr;
Or better, use a std::vector container:
#include <vector>
std::vector<int> arr(var);
To allocate an array dynamically, we use the array form of new and delete (often called new[] and delete[]):
#include <iostream>
int main()
{
std::cout << "Enter a positive integer: ";
int length{};
std::cin >> length;
int *array{ new int[length]{} }; // use array new. Note that length does not need to be constant!
std::cout << "I just allocated an array of integers of length " << length << '\n';
array[0] = 5; // set element 0 to value 5
delete[] array; // use array delete to deallocate array
// we don't need to set array to nullptr/0 here because it's going to go out of scope immediately after this anyway
return 0;
}
Arrays in C++ must have constant size known at compile-time. You can preallocate several constant sizes known at compile time and offer the user to choose one of them. Alternatively, you can use another data structure that allows dynamic size allocation e.g std::vector.
Good luck!

User defined size of array

I want to initialize an array with user defined size, but what know is- I've to declare an array of maximum size and then work on number of elements given by user in this process huge memory wastes. Is there any way to declare an array of size given by user.
I did this but compiler showed error.
int a=0;
std::cout<<"Enter size of array";
std::cin>>a;
const int b=a;
int ary[b];
I'm using Turbo C++IDE
The issue with your code is that you are declaring what is called a variable length array which is not part of C++ (though it is valid C code). See this for an explanation as to why.
You can achieve what you are trying to do in a few different ways though:
You could dynamically allocate an array using a user provided size:
#include <iostream>
#include <memory>
int main(int argc, char** argv)
{
std::size_t a =0;
std::cout<<"Enter size of array";
std::cin>>a;
std::unique_ptr<int[]> arr(new int[a]);
//do something with arr
//the unique ptr will delete the memory when it goes out of scope
}
This approach will work but may not always be ideal, especially in situations where the size of the array may need to change frequently. In that case I would recommend using a std::vector:
#include <iostream>
#include <vector>
int main(int argc, char** argv)
{
std::size_t a =0;
std::cout<<"Enter size of array";
std::cin>>a;
std::vector<int> arr(a);//arr will have a starting size of a
//use arr for something
//all of the memory is managed internally by the vector
}
You can find the reference page here.
You can use new keyword while declaring a dynamic array
int main()
{
int array_size;
std::cin >> array_size;
int *my_array = new int[array_size];
delete [] my_array;
return 0;
}
You should delete the array allocated with new.
You can also use vector for dynamic allocation of memory in c++. Read here for examples on vector

Error when trying to print out array in a loop using cout

#include <cstdio>
#include <iostream>
int main (){
int n;
std::cin>>n;
int*a;
for (int i=0;i<n;i++){
std::cin>>a[i];
}
for(int i=0;i<n;i++){
std::cout<<a[i];
}
return 0;
}
I just started working on a problem and I wanted to check if I knew how to read and array and make a sample output array. When I include the second loop program crashes as soon as I enter n and the first number With the following message
3 1
Process returned -1073741819 (0xC0000005) execution time : 4.943 s
Press any key to continue.
int *a; is a pointer to an integer, it is just a pointer to some memory, it has no memory allocated on its own. Since you are dereferencing this pointer a[i] without setting it up first, your compiler should even give you some warning telling that you are using a variable that has not been initialized.
0xC0000005 error code in Windows means access violation. In this case, you are trying to write to some memory which you don't have access to.
You need to allocate memory before you can read or write to it.
If you know beforehand how many entries you will have, you can do static memory allocation, if you don't, then you need to do dynamic memory allocation.
For instance, if you knew that you would need only 20 entries at max, you could easily swap int *a; for int a[20];.
But since you are only getting to know how many entries there will be when the program runs, then you need to go for dynamic memory allocation: int *a = new int[n];.
So your code should be
#include <cstdio>
#include <iostream>
int main (){
int n;
std::cin>>n;
int *a = new int[n];
for (int i=0;i<n;i++){
std::cin>>a[i];
}
for(int i=0;i<n;i++){
std::cout<<a[i];
}
delete[] a; // Release allocated memory.
return 0;
}
You need to allocate memory for a, otherwise the behaviour of the program is undefined. Writing
int* a = new int[n];
would to it, followed by delete[] a; when you're all done (put this just before return 0;).
Alternatively, use a std::vector<int> a(n); and all the memory allocation will be taken care of for you.
Try : int a[20]; rather than int *a;
Your a doesn't point to any valid memory, resulting in undefined behaviour.
What you need is an std::vector :
#include <vector>
int n;
std::cin>>n;
std::vector<int> numbers;
for (int i=0;i<n;i++){
int val;
std::cin>>val;
numbers.push_back(val);
}
for(int i=0;i<n /* or numbers.size()*/ ;i++){
std::cout<< numbers[i];
}
This takes care of dynamic allocation for you so that you don't have to do the dirty stuff yourself.
There are a few issues with your code. Primarily, you request the number 'n' then need to allocate enough space to store that many integers.
The best way to do that is to use vector. You can create this with:
std::vector< int > numbers( n );
You can also create it allocating the memory but waiting until you have data:
std::vector< int > numbers;
numbers.reserve( n );
You also should probably validate your input, for example your input stream (cin) will be invalid if the user enters something that is not an integer, and the original 'n' should be positive if you are going to try to create a vector of that size, and you may need to set a limit or you will suffer a bad_alloc. If you do not mind suffering a bad_alloc you should catch that exception and print an error such as "There is insufficient space to allocate as many numbers".
Of course if you enter a high number like 10 million, you may find the compiler is able to allocate that many but your user will get bored in your loop when you ask him to enter integers 10 million times.
You do not need <cstdio> as a header. You will need <vector> and <iostream>.
int* is a pointer to int, not an array.
To create an array of int, example: int a[100]; - where 100 is the size
Moreover, you should use a std::vector<int> instead:
vector<int> vec;
for (int i = 0; i != n; ++i) {
int temp;
cin >> temp;
vec.emplace_back(temp);
}

How to allocate memory dynamically using pointers?

I have the following task:
Creat a program that will transform array A to array B in the followin order:
http://gyazo.com/29e434ebdc1e235fe0fc97c26ae9fe9c
The size of A is entered by user, as well the elements. Print the new elements of B. "Use pointers"
Examples: If I input 1234567, the program will output 8888888.
Here's my code:
#include <iostream>
using namespace std;
int main()
{
int N;
cout << "Enter the size of array" << endl;
cin >> N;
int A[N], B[N];
cout << "Enter the elements of the array" << endl;
for(int i = 0; i < N; i++){
cin >> A[i];
}
for(int i = 0; i < N; i++){
B[i] = A[i] + A[N-i-1];
}
for(int i = 0; i < N; i++){
cout << B[i] << " ";
}
return 0;
}
There is only one problem I have, it says to "use pointers" but I don't know where shall I use them and they must be used... thanks in advance.
int A[N], B[N];
This code is non-standard (when N is a variable). Your compiler allows that, but if you try to compile this code in other one, it probably won't work.
Using pointers in this case means, that you should allocate memory for the arrays dynamically, eg.
int * A, * B;
A = new int[N];
B = new int[N];
This code is valid in terms of C++ standard.
Remember though, that you will have to free allocated memory manually after you don't need it anymore:
delete[] A;
delete[] B;
This should work with the rest of your code left unchanged, since [] operator works for pointers as well.
And finally, if you really are writing a C++ program, you surely should be using std::vector instead of C-style arrays...
Edit: (in response to comment)
If you declare a variable in the following way:
int * A;
And then write:
cin >> *(A + i);
It means:
Read data from user and parse it;
Go i "steps" starting from address A (it actually "walks" i * sizeof(*A) bytes from A).
Put the data read from the user to memory pointed to by place evaluated in step 2.
But when you declare:
int (*A)[N];
The A becames pointer to the array of N elements. Since array is convertible to a pointer to its first element, you may think of that previous line (for the sake of explanation) as
int ** A;
In such case compiler tries to do the same as I described earlier. But now it walks i pointers starting from A, not *int*s. Then it dereferences that pointer getting an int * and attempts to put there data written by user. But >> operator of cin is not able to translate text to a pointer and that's why compiler complains.
Foot note
While you're learning using pointers, you may think of <something> variable[] as being equal to <something> * variable pointing to the first element of that array. This is a lie (because array is not a pointer, but it's convertible to a pointer to its first element), but helps understanding what arrays do have in common with pointers. That's why you can think of
int (* A)[];
As a
int ** A;
Well, this
cin >> N;
int A[N], B[N];
is not valid ANSI C++. You cannot declare arrays with variable indices. So you need a way to declare variable length arrays, and one way is to use pointers and dynamically allocated memory using new[] (and then delete[]).
The other, preferable method would be to use a container such as std::vector.