Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!ucsd!usc!samsung!shadooby!mailrus!ncar!tank!mimsy!chris From: chris@mimsy.umd.edu (Chris Torek) Newsgroups: comp.std.c Subject: Re: C question (memory allocation and access) Keywords: memory access Message-ID: <20771@mimsy.umd.edu> Date: 15 Nov 89 10:10:34 GMT References: <5322@wpi.wpi.edu> Distribution: usa Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 70 In article <5322@wpi.wpi.edu> mhampson@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@cs.umd.edu Path: uunet!mimsy!chris