[comp.lang.c] Memory allocation / data access

jim@doctor.chem.yale.edu (James F. Blake) (03/16/91)

I have two questions: 1) Have I allocated the storage properly and 2) Is this
the most efficient way to access the data (i.e., monomer[].atom[].x).  
I am allocating storage for n-molecules, each with n-atoms and 3 coordinates.
Any information would be greatly appreciated.

  Jim

typedef struct {
  double          x;
  double          y;
  double          z;
} cartesian;

typedef struct {
  cartesian       *atom;
} solvent;

solvent        *monomer;

/* Allocate the necessary storage */

if ((monomer = (solvent *) malloc (nmol * sizeof (solvent *)))==NULL)
  exit(1);

for (i = 0; i < nmol; i++) 
  if ((monomer[i].atom = (cartesian *) calloc (natoms,sizeof(cartesian)))==NULL)
    exit(1);

/* check components */

for (k = 0; k < natoms; k++) {
  for (l = 0; l < natoms; l++) {
    xdis = fabs (monomer[i].atom[k].x - monomer[j].atom[l].x);
    ydis = fabs (monomer[i].atom[k].y - monomer[j].atom[l].y);
    zdis = fabs (monomer[i].atom[k].z - monomer[j].atom[l].z);
  }
}

harry@matilda.uk.sun.com (Harry Protoolis - Sun EHQ) (03/16/91)

Jim,

You might be better of using pointers instead of constantly dereferencing array
elements.

cartesian *a_atom, b_atom;

for (a_atom = monomer[i].atom, k = 0; k < natoms; k++, a_atom++) {
    for (b_atom = monomer[j].atom, l = 0; l < natoms; l++, b_atom++) {
        xdis = a_atom->x - b_atom->x;
        ydis = a_atom->y - b_atom->y;
        zdis = a_atom->z - b_atom->z;
    }
}

Your allocation looks alright to me, though if you're allocating largish arrays
on a smallish system (e.g. > 64K on a PC) you might be better off using a
linked list. Oh, and why do you use malloc the first time and calloc the
next ?, as they are both array allocations you should, strictly speaking, be
using calloc for both.

if ((monomer = (solvent *) calloc (nmol, sizeof (solvent *)))==NULL)

Regards
Harry

|> typedef struct {
|>   double          x;
|>   double          y;
|>   double          z;
|> } cartesian;
|> 
|> typedef struct {
|>   cartesian       *atom;
|> } solvent;
|> 
|> solvent        *monomer;
|> 
|> /* Allocate the necessary storage */
|> 
|> if ((monomer = (solvent *) malloc (nmol * sizeof (solvent *)))==NULL)
|>   exit(1);
|> 
|> for (i = 0; i < nmol; i++) 
|>   if ((monomer[i].atom = (cartesian *) calloc (natoms,sizeof(cartesian)))==NULL)
|>     exit(1);
|> 
|> /* check components */
|> 
|> for (k = 0; k < natoms; k++) {
|>   for (l = 0; l < natoms; l++) {
|>     xdis = fabs (monomer[i].atom[k].x - monomer[j].atom[l].x);
|>     ydis = fabs (monomer[i].atom[k].y - monomer[j].atom[l].y);
|>     zdis = fabs (monomer[i].atom[k].z - monomer[j].atom[l].z);
|>   }
|> }

-- 
(smart Internet mailers) harry.protoolis@uk.sun.com
(smart JANET mailers) harry.protoolis@sun-microsystems.co.uk
(dumb uucp mailers) ...!sun!sunuk!harry.protoolis

'When I give food to the poor they call me a saint.
 When I ask why the poor have no food they call me a communist.'
         - Dom Helder Camara

mwb@ulysses.att.com (Michael W. Balk) (03/17/91)

In article <29491@cs.yale.edu>, jim@doctor.chem.yale.edu (James F. Blake) writes:
> 
> I have two questions: 1) Have I allocated the storage properly and 2) Is this
> the most efficient way to access the data (i.e., monomer[].atom[].x).  
> I am allocating storage for n-molecules, each with n-atoms and 3 coordinates.
> Any information would be greatly appreciated.
> 
> 
	.
	.
	.
> 
> if ((monomer = (solvent *) malloc (nmol * sizeof (solvent *)))==NULL)
>   exit(1);

	.
	.
	.


In answer to your first question I see an error in malloc.
Instead of sizeof(solvent *), you should have sizeof(solvent), i.e.,
you want to allocate space for nmol of solvent, not pointers to solvent.
Malloc then returns a pointer to the start of this space (type char* or void*),
which you have then correctly cast to a pointer to solvent.






Michael W. Balk
AT&T Bell Laboratories
Murray Hill, NJ 07974
mwb@ulysses.att.com

torek@elf.ee.lbl.gov (Chris Torek) (03/20/91)

In article <5654@male.EBay.Sun.COM> harry.protoolis@uk.1.com writes:
>... why do you use malloc the first time and calloc the
>next ?, as they are both array allocations you should, strictly speaking, be
>using calloc for both.

Well, no: calloc(n,s) is *exactly* the same as

	malloc(n * s)

plus (if the malloc succeeds) a call to memset to set all n*s `char's
to '\0'.  If the objects you are allocating hold something other than
integral types, this `zeroing' is not useful since other types
(i.e., pointers and floating types) may not have all-bits-zero `0'
values.  For instance, some machines use `ring 7' for all nil pointers,
or a special bit for all floating point values meaning `do not trap
when this floating point value is examined'.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov