C question (memory allocation and access)

Chris Torek chris at mimsy.umd.edu
Wed Nov 15 21:10:34 AEST 1989


In article <5322 at wpi.wpi.edu> mhampson at wpi.wpi.edu (Mark A. Hampson) writes:
[edited slightly]
>int   m = 10, n = 10, block_siz;
>void *block;
>block_siz = 2*sizeof(int) + m*n*sizeof(double);
>block = malloc(block_siz);

>I now wish to put two integers at the begining of this block of memory:
>
>block = m;
>(block+sizeof(int)) = n;   <---  here is where I am running into probs.
>
>My intention is to store m in the first int sized space in block and to 
>store n in the int sized space after it.

You could write:

	((int *)block)[0] = m;
	((int *)block)[1] = n;

or any equivalent combination.  This code is valid, if a bit twisty.
However, I am guessing from the value in block_siz that you then intend
to put m*n `double's in the memory region after the first two int-sized
blocks.  This is not easy, because that region may not be properly
aligned for a double.  Consider, e.g., a machine with 4-byte ints,
16-byte doubles, and 16-byte data paths, that requires 16-byte objects
to be aligned on a 16-byte boundary.  If you take the obvious approach:

	int *iptr = block;
	double *dptr = (double *)&iptr[2];
	iptr[0] = m;
	iptr[1] = n;
	dptr[0] = 1.234;

the assignment to dptr[0] will cause a run-time alignment error fault.

There is an almost-portable solution:

	struct mat2 {		/* 2 dimensional dynamic matrix */
		int	m;
		int	n;
		double	data[1];/* actually larger */
	};

	int m = 10, n = 10;	/* as before */
	size_t sz = sizeof(struct mat2) + (m * n - 1) * sizeof(double);
	register struct mat2 *mat;
	register double *d;

	if ((mat = malloc(sz)) == NULL) {
		/* do not know what printf format to use for `size_t',
		   hence the cast to unsigned long */
		panic("cannot allocate %lu bytes for matrix",
		    (unsigned long)sz);
		/* NOTREACHED */
	}
	mat->m = m;
	mat->n = n;
	d = mat->data;
	for (i = m * n; i != 0; i--)
		*d++ = 0.0;

The `sizeof(struct mat2)' includes any padding that must be inserted
between the second `int' object and the `double's that will go there.
m*n is the number of doubles, but one is already included in the
structure, so we have to subtract that off before multiplying by
sizeof(double).
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at cs.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.std.c mailing list