Making an array of arrays

An illustration of the process (one way to do the deed):

// Demonstration of 2-D array in PROGMEM.
// It's not necessarily a "matrix" since
// each "row" can have a different number of
// elements ("colunmns").
//
// The principle is the same as would be used
// for dynamically-allocated 2-D arrays on
// a Princeton (Von Neumann) machine, but because
// of the Harvard architecure of the ATmega, we
// can't use the convenient 2-D notation that we
// all know and love so much.
//
// Oh, well...
// 
//
// davekw7x

#include <avr/pgmspace.h>

// A couple of typedefs for variables that
// will be in PROGMEM.
typedef float PROGMEM const prog_float;
typedef int   PROGMEM const prog_int;

// 2-D array is created by using an array of pointers.
// Each pointer is the address of a row of the 2-D array.
// I'll define a pointer to a float in PROGMEM.
// (Left as an exercise: Do it with a typedef instead of #define)
#define PFLT const prog_float *


// First define the "rows" of the 2-D array
PROGMEM prog_float row0[] = {
    1.23,
    4.56,
    PI
};

PROGMEM prog_float row1[] = {
    4.5,
    6.7
};


// Table of addresses of the "rows" of the 2-D array
PROGMEM prog_float * table[] = {
    row0, // Address of row0[0]
    row1  // Address of row1[0]
};
// For each row, these give the number of elements on each row
const int ROW0_SIZ = sizeof(row0)/sizeof(row0[0]);
const int ROW1_SIZ = sizeof(row1)/sizeof(row1[0]);


// This is a table of ints that give sizes of the individual "rows" of the 2-D array
PROGMEM prog_int rowsizes[] = {
    ROW0_SIZ,
    ROW1_SIZ
};

// This is the number of "rows"
const int TABLE_SIZ  = sizeof(table)/sizeof(table[0]);


void setup()
{
    Serial.begin(9600);    
}

void loop()
{
    // For each row
    for (unsigned i = 0; i < TABLE_SIZ; i++) {
        int tablei_siz = (int)pgm_read_word(rowsizes+i);
        for (unsigned j = 0; j < tablei_siz; j++) {
            PFLT pf = (PFLT)pgm_read_word(table+i);
            float x = pgm_read_float(pf+j);
            Serial.print("x[");
            Serial.print(i);
            Serial.print("][");
            Serial.print(j);
            Serial.print("] = ");
            Serial.println(x);
        }
        Serial.println();
    }
    Serial.println();
    delay(10000);
    Serial.println();
}

Output:


x[0][0] = 1.23
x[0][1] = 4.56
x[0][2] = 3.14

x[1][0] = 4.50
x[1][1] = 6.70

To get anything out of the table, you have to know where the table of row sizes is and how many rows there are. I mean, you could store the number of rows somewhere, but where will it end??? How much do you really need to know about the table?

Regards,

Dave