a pointer is essentially a variable which contains a memory address of an object. Type of an object in your case is 'int'.
memory:
00000000: [some value] -- start
...
pointer : [address1] pointer to int (int*) +
... |
address1: [value of int] <-----------------+
now what you have is int**
which is a pointer to pointer to int.
memory:
00000000: [some value] -- start
...
pointer : [address1] pointer to int (int**) ----+
... |
address1 : [address2] pointer to int (int*) + <-+
... |
address2: [value of int] <------------------+
Now, what you did, you allocated an array of pointers to int of size row
memory:
00000000: [some value] -- start
...
pointer : [address1] pointer to int (int**) -----+
... |
address1 : [address-a] pointer to int (int*) + <-+
address2 : [address-b] pointer to int (int*)
address3 : [address-c] pointer to int (int*)
address4 : [address-d] pointer to int (int*)
address5 : [address-e] pointer to int (int*) +
... |
address-e: [value of int] <------------------+
...
address-b:...
hope it helped