3

What we're being taught at school is this:

int x;
cin >> x;
int array[x];

OR

int x, y;
cin >> x >> y;
int array[x][y];

However, I am aware that it's invalid code in C++. But even if it is, it still does the job and works as expected, however, I'm looking to find the answer of how it's properly done?

user2699298
  • 1,446
  • 3
  • 17
  • 33
  • 1
    Search the web or StackOverflow for "C++ matrix implementation". The C++ FAQ has a good discussion on overloading operators for accessing a matrix. – Thomas Matthews Dec 02 '13 at 20:53

4 Answers4

5

This is not standard C++ but many compiler including gcc and clang support variable length arrays as an extension in C++ even though it is a C99 feature. Althought both gcc and clang will warn you this is an extension if the -pedantic flag is used with a message similar to this:

warning: ISO C++ forbids variable length array ‘array’ [-Wvla]

An alternative in standard C++ would be to use std::vector or dynamic allocation via new:

int x;
cin >> x;
int *array new int[x] ;
//...
delete [] array ;

the 2D dynamic allocation case is well covered in How do I declare a 2d array in C++ using new?. Using a container is probably better since you do not have to worry about deleting the allocated memory afterwards.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
5

Properly it is done with dynamic arrays:

int x;
cin >> x;
int* array = new int[x];

Note, that in this case it is your responsibility to free the allocated memory; or use smart pointers.

Another approach is using STL containers, e.g. vector.

mcserep
  • 3,231
  • 21
  • 36
  • I would go for `int *const array` ;) – user2485710 Dec 02 '13 at 20:48
  • Don't forget `delete`, and exception-safety precautions, if you really want to muck around with low-level pointer juggling. – Mike Seymour Dec 02 '13 at 20:49
  • @MikeSeymour: I thought it was obvious, but I extended my answer, thanks for the note. – mcserep Dec 02 '13 at 20:53
  • @user2485710: Please explain why it is better to use a constant pointer in a general situation? – mcserep Dec 02 '13 at 20:54
  • @CMate because const-correctness is a really good philosophy and you should stick with it whenever it's possible in C++. It will also help you in debugging your application, because if you try to modify `array` you will get an error, this way you are sure that `array` will always point where you think it's pointing, anywhere in the code. – user2485710 Dec 02 '13 at 20:59
  • @user2485710 I see your point and its advantages, but what if I would like to `delete` the array and point the variable to a new array? Or, with this concept I shouldn't do that, and rather initialize a new variable instead? That could be messy sometimes. – mcserep Dec 02 '13 at 21:04
  • @CMate in that case you probably should switch to "real" C++ containers, it will be messy anyway with raw pointers and arrays. – user2485710 Dec 02 '13 at 21:07
3

Usually it is done either by using standard container std::vector or by allocating the array dynamically in the heap. For example

int x, y;
cin >> x >> y;
int **array = new int * [x];

for ( size_t i = 0; i < x; i++ ) array[i] = new int[y];
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • It would be better to use int i = 0 in the loop instead of size_t i = 0 because x is declared as int. I simply did not take into account that x is defined as int.:) – Vlad from Moscow Dec 02 '13 at 20:51
3

The most straightforward way to get a dynamically sized array is with std::vector:

int x;
cin >> x;
vector<int> array(x);

Multidimensional arrays are a bit more complicated; one option is:

int x, y;
cin >> x >> y;
vector<vector<int>> array(x, vector<int>(y));

More efficiently, but less simply, you might consider using a one-dimensional array of size x*y, with accessor functions to treat is as two-dimensional.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644