This is what I'm suggesting.
Code:
mat= malloc((nrows+index)*sizeof(double*));
Setting mat[0] = NULL will simply meant that if, for some reason, the code tries to access mat[0][x] later on, it will fail, rather than do something random that may or may not crash (and may or may not launch nuclear missiles, make the aeroplane fall out of the sky, etc).
Of course, if index is zero, then you will overwrite the mat[0] with a memory allocation. If it's 1, then you get no memory allocated for that bit, so it remains NULL and thus will be "obvious" if it's accidentally used.
Re size_t
Code:
void iarray2d(int **mat, size_t nrows, size_t ncols, int index)
There should be no reason to use "long" here - size_t is the same size as long (in Linux at least, if you are using Windows it isn't in 64-bit versions of Windows - but then you probably still want size_t rather than long in those cases, as it will allow you to allocate more than 4GB of memory).
By the way, size_t _IS_ a regular type - it's just specifically defined to match the largest allocation you can possibly make.
--
Mats