Retraction (matrix routine)

Jim Hester hester at ICSE.UCI.EDU
Wed Nov 20 05:25:28 AEST 1985


The make_mat procedure given assumes that double pointers are the same
size as doubles, and further assumes doubles are the data type.  The second
assumption may not matter in a given program, but the first might easily
trash the program if ported to a system where pointers are not equivelent
(size-wise) to doubles.  The following corrects this, and is consistant
in usage with malloc and calloc.  From your example I infer that valloc
is no different.

	char *malloc();
 
	char **make_mat (rows, cols, elt_size)
	int rows, cols, elt_size;
	{
		char	**result;
		int	i;

		result = (char **) malloc (rows * sizeof(char *));
		result[0] = (char *) malloc (rows * cols * sizeof(char *));
		for (i = 1; i < rows; i++)
		    result[i] = result[i-1] + cols*elt_size;
		return (result);
	}

	void free_mat (matrix)
	char **matrix;
	{
		free( matrix[0] );
		free( matrix );
	{

The call for an N by M matrix of doubles would then be:

	double **matrix;
	matrix = (double **) make_mat( N, M, sizeof(double) );
and to free:
	free_mat( (char **) matrix );


The previous code still assumes that all pointers (ie char and double
pointers) are of the same size.  I generally allow this assumption
since I like the calling syntax and tend to think that pointers WILL
be the same size (ie byte addresses to the head of whatever type),
but if you want to avoid this potential problem you may resort to
macros at a slight degridation (in my opinion) of calling syntax:

	char *malloc();
 
	#define make_mat (matrix, rows, cols, type)\
	{\
		int	i;\
		int	rws = rows;	/* to precalculate expressions */\
		int	cls = cols;\
\
		matrix = (type **) malloc (rws * sizeof(type *));\
		matrix[0] = (type *) malloc (rws * cls * sizeof(type));\
		for (i = 1; i < rws; i++)\
		    matrix[i] = matrix[i-1] + cls;\
	}

	#define free_mat(matrix)\
	{\
		free( (char *) matrix[0];\
		free( (char *) matrix;\
	}

The call should now be:
	double **matrix;
	make_mat(matrix, N, M, double);
and to free:
	free_mat(matrix);
	

WARNING:  I have not tested any of this code.  I believe it to be sound
in theory, but may need debugging.  I kind of doubt it though---it's
fairly straightforward stuff that I've used before.



More information about the Comp.sources.unix mailing list