0

I would like to determine if there is a way to determine whether a dynamically allocated matrix is square (nxn).

The first thing that came to mind was to see if there is a way to find out whether a pointer is about to point to an invalid memory location. But according to these posts:

C++ Is it possible to determine whether a pointer points to a valid object?

Testing pointers for validity (C/C++)

This cannot be done.

The next idea I came up with was to somehow use the sizeof() function to find a pattern with square matrices, but using sizeof() on a pointer will always yield the same value.

I start off by creating a dynamically allocated array to be of size nxn:

int **array = new int*[n]
for(int i = 0; i < n; i++)
    array[i] = new int[n];

for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j++){
        array[i][j] = 0;
    }
}

Now I have a populated square matrix of size nxn. Let's say I'm implementing a function to print a square 2D array, but a user has inadvertently created and passed a 2D array of size mxn into my function (accomplished by the code above, except there are more row pointers than elements that comprise the columns, or vice versa), and we're also not sure whether the user has passed a value of n corresponding to n rows or n columns:

bool(int **arr, int n){
    for(int rows = 0; rows < n; rows++)
        for(int cols = 0; cols < n; cols++)
            cout << *(*(arr + rows) + cols) << " ";
            // Is our next column value encroaching on unallocated memory?  
        }
        cout << endl;
        // Is our next row value out of bounds?
    }
}

Is there any way to inform this user (before exiting with a segmentation fault), that this function is for printing square 2D arrays only?

Edit: corrected 3rd line from

array[i] = new int[i]

to

array[i] = new int[n]
omri
  • 352
  • 2
  • 18
  • 1
    You didn't create a _nxn_ matrix. The line `array[i] = new int[i];` is wrong... – Blastfurnace Sep 18 '19 at 04:54
  • 1
    For a matrix, I wouldn't allocate each row individually. Why not a class MatrixNxN with contiguous storage in a `std::vector` and the resp. member functions to support access with one index or two indices? (like e.g. here: [SO: C++ Matrix Class](https://stackoverflow.com/a/2076668/7478597)) – Scheff's Cat Sep 18 '19 at 05:13
  • How would the user pass in a mxn matrix? Would you be asking for the no of rows and columns in the matrix? or would it be created by a function? – Christina Jacob Sep 18 '19 at 05:13
  • When manually handling memory allocation with `new` and `delete`, YOU the programmer are responsible for keeping track of what you have allocated. Which is a big reason why use of the containers library is recommended. There is nothing wrong with `new/delete` and there is a lot of existing code that makes use of it, but in using them, the responsibility for tracking each allocation until it is no longer needed and freed is all up to you. – David C. Rankin Sep 18 '19 at 05:34

1 Answers1

3

There is NO way to find out information about an allocation. The ONLY way you can do that, is to store the information about the matrix dimensions somewhere. Pointers are just pointers. Nothing more, nothing less. If you need something more than a pointer, you'll need to define a type that encapsulates all of that information.

class Matrix2D
{
public:

  Matrix2D(int N, int M)
    : m_N(N), m_M(M), m_data(new int[N*M]) {}

  int N() const { return this->m_N; }
  int M() const { return this->m_M; }

  int* operator[] (int index) const
    { return m_data + m_M * index; }

private:
  int m_N;
  int m_M;
  int* m_data;
};
robthebloke
  • 9,331
  • 9
  • 12
  • You could probably add an `is_square()` member function to address all parts of the question. (what you have isn't wrong, it just doesn't answer the entire question) – David C. Rankin Sep 18 '19 at 05:36