Retraction (matrix routine)
Chris Torek
chris at umcp-cs.UUCP
Wed Nov 20 17:02:01 AEST 1985
Your routine may not work on machines with severe alignment
constraints. More important, however, is your use of `valloc'.
`valloc'ed memory is page aligned, normally only used in cases
where a virtual memory system wants to move it around by changing
PTEs rather than by copying; moreover, this memory cannot be given
back on a standard system (I consider this a bug in valloc, but it
is there.)
Here is a `portable' matrix allocator that uses `malloc', along
with a matrix destroyer. The remaining routines are left as an
exercise to the reader....
/*
* matalloc.c - matrix allocation and freeing routines.
*/
#define NULL 0 /* standard, portable, and correct! */
char *malloc(); /* eventually `char *malloc(int n);' */
void free(); /* eventually `void free(char *p);' */
/*
* This type belongs in mat.h, but I am creating this on the fly
* and want a self-contained example. Separate this out before
* using these routines in `real live code'.
*/
typedef struct matrix {
int m_rows; /* number of rows */
int m_cols; /* number of columns */
double **m_data; /* the base of the row set */
} MATRIX;
/*
* Create a matrix of size `rows' by `cols', and initialize
* it to contain all `init' values. Return a pointer to the
* new matrix, or NULL for failure.
*/
MATRIX *
mat_alloc(rows, cols, init)
int rows, cols;
double init;
{
register int j, i;
register double *cp, **rp;
register MATRIX *m;
/*
* Allocate the matrix descriptor.
*/
if ((m = (MATRIX *)malloc(sizeof *m)) == NULL)
return (NULL);
/*
* Allocate the row vector.
*/
if ((rp = (double **)malloc(rows * sizeof (double *))) == NULL) {
free((char *)m);
return (NULL);
}
m->m_data = rp;
/*
* Allocate each of the column vectors. It is safe to allocate
* one large array now and break it up into pieces; indeed, this
* uses less memory and makes error recovery simpler here.
*
* (Pardon my `count down to zero' style; I use it when only the
* number of trips through the loop is of interest, not the index
* itself. It generates better code on many machines....)
*/
if ((cp = (double *)malloc(rows * cols * sizeof (double))) == NULL) {
free((char *)rp);
free((char *)m);
return (NULL);
}
for (i = rows; --i >= 0;) {
*rp++ = cp; /* record position of this column */
for (j = cols; --j >= 0;)
*cp++ = init; /* and initialize it */
}
return (m);
}
/*
* Free the matrix `m'.
*/
void
mat_free(m)
register MATRIX *m;
{
free((char *)*m->m_data); /* free the column array */
free((char *)m->m_data); /* and the row vector */
free((char *)m); /* and finally the descriptor */
}
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP: seismo!umcp-cs!chris
CSNet: chris at umcp-cs ARPA: chris at mimsy.umd.edu
More information about the Comp.sources.bugs
mailing list