can you elaborate on this a bit more?

TL;DR Matrix don’t need to be [][] they can be seen as a simple view on a [] array when you have a rectangular array with simple math. And, you can use sparse matrix in other cases too. Which handles 80% of the common cases. A matrix, is an abstraction. It seldom needs to be a [][].

This is not C, but it the idea, here I implement matrix as either sparse matrix (sets of coordinate, dicts) or using x = offset modulo col_size and y = int(offset)/ col_size on any 1D arrays. Hence since Game Of Life is arrays of state in (Alive (0), Dead (1)) I use an integer as a matrix. I can keep a matrix of 1024 x 1024 states stored in a memory efficient way without the overhead of the boxing model in python.

I keep a 2D API for keeping the code easier to read (for me).
Boundary conditions are thus in pretty simple forms:
offset == (offset % line_size in (line_size -1, 0) ) or (col_size >offset >= col_size -1 * line_size) (testing my cider and being dyslexic my code may not be exact) which makes boundary conditions explorable within a single indexed loop (that CPU very easily can heavy lift (SSE?) and a simple “?:”. And I avoid the burden of double memory allocs (even worse in C).

I also can also copy with single loops (memset in C) 2D arrays.

Does it answer your question? 
I thought it was simple, but discovered to my dismay that many CS teachers consider this an heresy in my beautiful elite country and prefer the [][] approach systematically (even for rectangular 2D matrices, framebuffers, pixmaps…) especially in elite school (sarcasm towards my educational system).

Here is a troll^H rant I made on the topic

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.