Dynamic allocation 2d array

Nov 14, 2013 at 12:44pm
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
Nov 14, 2013 at 12:50pm
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 Nov 14, 2013 at 12:51pm
Nov 14, 2013 at 1:43pm
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 Nov 15, 2013 at 10:03am
Nov 14, 2013 at 8:39pm
*bump*
Nov 14, 2013 at 9:09pm
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.
Nov 14, 2013 at 9:33pm
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

Nov 14, 2013 at 10:40pm
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.