можно не ограничиваться 2D
Как вариант — подсмотреть реализацию ndarray в Numpy.
Частично описано
здесь (на англ.)
Данные хранятся в буфере – типа массива в C. И есть метаданные, описывающие "вид" на этот буфер.
Когда меняется форма, создаётся новый объект метаданных, без изменений в самих данных.
Но тут не раскрывается тема вставки, как это изменяет размер буфера – создают новый или расширяют старый. В конце или распихивают по строкам.