Dynamic allocation 2d array

I need someone knowledgeable enough to confirm that this problem cannot be solved without a pointer. Namely I need to read the rows and columns number from the user cin >> m, n and then use to declare an array int A[m][n];

However as m and n are not constants I am not able to do that. Is there a workaround? The following is the solution I came with BUT using a pointers which should be not the case.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// solution with using pointers as "int A[m][n]" does not work for me!!!
void TwoDimensionalArrayFunc(){
	int m = 0;
	int n = 0;
	
	// instruct the users to enter array dimensions
	cout << "Please insert value for m:";
	cin >> m;
	cout << endl;
	cout << "Please insert value for n:";
	cin >> n;
	cout << endl;

	// I am using the pointers because C++ doesn't support the array dimensions with sizes 
	// not known at compile time ("allocated types") (our dimensions are not constants).
	int **A = new int*[m];
	for(int i = 0; i < m; ++i) {
		A[i] = new int[n];
	}

	

	cout << "Insert values:\n";
	
	// read the user inputs
	for (int i = 0; i < m; i++){
		for (int j = 0; j < n; j++){
			cout << "A[" << i << "][" << j << "]:";
			cin >> A[i][j];
			cout << endl;
		}
	}

	// variables to be used for the final output
	int smallest = 0;
	int largest = 0;
	int difference = 0;

	// find the largest number 
	for (int i = 0; i < m; i++){
		for (int j = 0; j < n; j++){
			if(largest < A[i][j]){
				largest = A[i][j];
			}
		}
	}

	
	// find the smallest number 
	smallest = largest;
	for (int i = 0; i < m; i++){
		for (int j = 0; j < n; j++){
			if(smallest > A[i][j]){
				smallest = A[i][j];
			}
		}
	}

	// compute the difference
	difference = largest - smallest;

	cout << "The smallest element in the array is: " << smallest << endl;
	cout << "The largest element in the array is: " << largest << endl;
	cout << "The difference between them is: " << difference << endl;

	// clean up
	// everything that is allocated with 'new' is created on the heap and must be de-allocated with delete.
	// meaning, it has to be deleted from the heap to prevent a memory leaks.
	for(int i = 0; i < m; ++i) {
		delete [] A[i];
	}
	delete [] A;
}


Thank you so much in advance
With normal arrays and without pointers I think this can't be solved. But it is possible with (multidimensional) vectors: http://www.cplusplus.com/reference/vector/vector/ and http://en.cppreference.com/w/cpp/container/vector
Last edited on
Actually I am trying to find a solution using C-style C++ which means no std::vectors, std::array and such. I have a guy claiming that it can be solved without pointers but never showed me the solution.
Thank you for your opinion. It's much appreciated.

I'll be waiting for someone else to confirm this before I announce that it cannot be solved without pointers.

Thank you again

Last edited on
*bump*
Read up on the memory layout of multidimensional arrays, and how to index them, here:
http://www.cplusplus.com/faq/sequences/#what-is-a-md-array

All you need is a function to index the data. Something like:

1
2
3
4
5
template <typename T>
T& index( T* a, std::size_t columns, std::size_t row, std::size_t col )
{
  return a[ (columns * row) + col ];
}

It is a little cumbersome to use. I dislike the std::array class -- I think it has serious problems (mainly, it is type-incompatible with other arrays -- one of the original complaints against Pascal in Kernighan's famous paper) and it uses up a useful name in the std namespace (contaminating it's usefulness for those who want a better array class).

That rant aside, you can easily create a class to manage a variable-sized 2D array, which you can use almost identically to a normal 2D array. All you need to overload is the [] operator (to return a pointer to the first element in each row). Ideally, you could do something like:

1
2
3
4
5
array2d <int> xs( 3, 4 );  // == int xs[ 3 ][ 4 ]

xs.resize( 4, 4 );  // oh, wait, I meant xs[ 4 ][ 4 ]

xs[ 1 ][ 2 ] = 7;  // xs[ 1 ] returns pointer to beginning of row, [ 2 ] index element in row 

etc.

Such a class can be as simple or complex as you like.

Hope this helps.
Thanks for replying Duoas. It's greatly appreciated.
However I need someone to either confirm that this problem CANNOT be solved WITHOUT POINTERS or post a C-Style solution using int A[m][n]; where m & n are entries from the user cout << m; cout << n;

As mentioned I believe that its not even possible but I want to be 100% sure about it.

Thank you so much

Compile with -std=c11

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
  {
  unsigned m, n;

  printf( "m? " );
  fflush( stdout );
  scanf( "%u", &m );

  printf( "n? " );
  fflush( stdout );
  scanf( "%u", &n );

  int a[ m ][ n ];

  memset( (void*)a, 0, sizeof(int) * m * n );

  a[ 1 ][ 2 ] = 7;

  for (unsigned i = 0; i < m; i++)
    {
    for (unsigned j = 0; j < n; j++)
      {
      printf( "%u ", a[ i ][ j ] );
      }
    printf( "\n" );
    }

  return 0;
  }

This doesn't help you, though, since your functions to work on the array still need to index the data.

And the only way to do that is via pointer arithmetic, like I posted above.
Topic archived. No new replies allowed.