You declared ptr as "int *ptr" which means "ptr points to a 1-dimensional memory location that contains an int". And in C a pointer for the most part is equivalent to an array (which is also a pointer to a memory location).
Then you assign it a value "ptr = arr" which now means "ptr points to memory location which contains an int"
Now you can deference either with *ptr (which means "return the value in memory location pointed to by ptr") or with ptr[0] (which means "retrieve the first element of the array in memory location pointed to by ptr"). Both would return the same value - the value in memory location ptr
So, doing "ptr[0] +1" means "retrieve the first element in memory location pointed to by ptr, and then add 1 to that retrieved value".
The primary problem with your code is that you declared a two-dimensional array (and btw - you declared a 1x2 array but filled it with a 2x2 set of initial values), but then you declared a one-dimensional pointer to access it with. Perfectly valid in C as it provides infinite ways to shoot your own foot with, but not what you wanted.
I suggest turning on all compile warnings - you should get a number of them in your code snippet...