7

Is it possible to allow the user to enter the size of an array with a keyboard?

I know that arrays can't change size. The only solution I could think of is this:

int userSize;

cin >> userSize;

const int SIZE = userSize;

int array[SIZE];

How can I verify that this works? Should I use a vector instead?

Moshe
  • 57,511
  • 78
  • 272
  • 425
  • 2
    What you're looking for are variable-length arrays. They're not in C++ unless you use compiler extensions. – Mysticial Nov 25 '11 at 16:22
  • What's stopping you from trying this code? – user229044 Nov 25 '11 at 16:22
  • 1
    Do you insist on static allocation ? I reckon better solution would be to use type *userArray = new type[numberInputByUser]. DONT FORGET TO DELETE IT AFTERWARDS! :) – ScarletAmaranth Nov 25 '11 at 16:23
  • 3
    What's wrong with `std::vector array( userSize )`. That will work. – James Kanze Nov 25 '11 at 16:23
  • The "keyboard" part of the question is a red herring. The following also works: `echo 10 | ./myprog` – Kerrek SB Nov 25 '11 at 16:26
  • 2
    Trying is great, but just because it "works" doesn't mean it works, and we can certainly give better general knowledge about the situation on this site. For example, even if this works on your compiler, you better not try allocating more than ~4mb on the stack! – tenfour Nov 25 '11 at 16:27
  • Would it be easier with the mouse? – sehe Nov 25 '11 at 16:27
  • As a side note you cannot assign a `const` to a run time variable. That is what const means here. It cannot change. – Joe McGrath Nov 25 '11 at 17:58
  • @ScarletAmaranth: Anytime you thin "don't forget to..." you're doing it absolutely wrong. That should go in the destructor of a class, and that class should have proper copy/move semantics. `delete[]` ought to never exist in client code. – GManNickG Nov 27 '11 at 03:10
  • @GMan You have absolutely missed my point fine sir :) I wasn't going into details or anything like that, i just provided a little heads up on a very high abstract level :) I have never typed ' delete[] ' as you might have noticed, just sayin' ;) – ScarletAmaranth Nov 27 '11 at 03:13
  • @ScarletAmaranth: My point is that if you're going to give advice, make it worthwhile advice and not bad advice you don't even follow. – GManNickG Nov 27 '11 at 04:15
  • @GMan So you think that the advice of dynamic allocation was a bad advice kind sir? Or possibly the idea of freeing resources was a bad advice ? – ScarletAmaranth Nov 27 '11 at 12:10
  • @ScarletAmaranth: If you'll read my first comment, it's the advice that the memory management should be done manual ("Don't forget to delete it...") – GManNickG Nov 27 '11 at 21:15
  • @GMan You said it should go into destructor so that it's always taken care of by a compiler which i agree with but you still need to NOT forget to put it there, therefore not forgetting to free resources :) We should drop this, wish you best of luck kind sir. – ScarletAmaranth Nov 27 '11 at 21:24
  • @ScarletAmaranth: No, you use `std::vector` **which has already done that for you**. – GManNickG Nov 27 '11 at 21:27
  • @GMan I did provide a simple alternate solution and added a little bit of general programming advice. I didn't post it as a fully fledged answer, just a comment. Yes, using std::vector is even better than handling dynamic allocation and deallcoation manually, you're very correct dear sir. – ScarletAmaranth Nov 27 '11 at 21:31
  • @ScarletAmaranth: "Yes, using std::vector is even better than handling dynamic allocation and deallcoation manually" So then as I said *from the start*, just say this *instead of bad advice*. – GManNickG Nov 27 '11 at 21:38
  • @GMan It' certainly NOT a bad advice. It does provide a solution to a problem he presented. – ScarletAmaranth Nov 27 '11 at 22:16
  • @ScarletAmaranth: I think we're done. You apparently can't make up your mind on what the better solution is, and don't recognize (for whatver reason) that manual memory management is bad, a well-established principle in C++. – GManNickG Nov 27 '11 at 22:25

5 Answers5

18

Variable Length Arrays are not approved by C++ standard. C++ Standard mandates that the size of an array must be an compile time constant.
You can use VLA's through compiler extension provided in gcc but note the your code is not portable if you do so.

Standard approved way of doing this is to use std::vector.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
12

Many of the other answers are correct, but to show your possible choices. Each one will fit into different situations better.

The first one is most similar to your code. It makes a constant size array and lets the user choose how much of it to use. This is simple, but limiting. It can waste unused space, but has it places to be used. (not likely based on user input though)

const int SIZE=100;
int array[SIZE];
int userSize;

cin >> userSize;
if (userSize>SIZE){
   cerr << "Array requested too large";
}
// use userSize as size of array

The second choice is dynamic memory allocation and using a regular C pointer to keep track of it. If you forget (or are unable) to delete it you have a memory leak.

cin >> userSize;
int* array = new int[userSize];
...
delete [] array;

The third choice is writing your own smart pointer, boost, or in C++ 0x a unique_ptr. It will keep track of the pointer for you and delete it when it goes out of scope.

cin >> userSize;
unique_ptr<int[]> array(new int[userSize]);

And finally you probably just want a vector. As you hinted to in your question, a vector is probably the way to go here. They are simple, efficient, and commonly used. Learning one stl container makes learning the others easier. You should research which container fits your current problem best. Vector is a good choice most of the time.

#include <vector>
...
std::vector<int> vec; 
cin >> userSize;
vec.resize(userSize);
Joe McGrath
  • 1,481
  • 10
  • 26
1

Yes you can. Here it is:

int n;
cout << "enter degree ";
cin >> n;
int *arr = new int[n];
Peter Hall
  • 53,120
  • 14
  • 139
  • 204
shehab
  • 27
  • 1
1

No, arrays cannot be variably sized in C++. The code you have there will not compile, because the value of a constant has to be evaluated at compile-time.

You might try the std::vector class instead and use the resize method, or pass the size through the constructor. Although, depending on what you need, maybe you can just let it grow naturally by using push_back.

A lower-level alternative is to use dynamically allocated arrays:

int userSize;
cin >> userSize;
int* array = new int[userSize];
mhelvens
  • 4,225
  • 4
  • 31
  • 55
0

No, you can't have dynamic allocations like that on the stack (yes, I know, some compilers have extensions for this, but generally speaking the answer is no). You'd want to use malloc or new to dynamically allocate room on the heap. Or of course there are always structures to make life easier, like vector.

Chris Eberle
  • 47,994
  • 12
  • 82
  • 119