• C

Arrays of nested structures - cannot allocate memory - HELP

I am trying to build a molecular model of a material. Each material is composed of a user specified number of molecules and each molecule cis composed of a set number of atoms. I am trying to allocate memory to this structure as follows (please ignore the printf's as they are mainly for debugging purposes):

System *GenerateNewSystem () {
 
    int temp;
    int temp_check;
    int dummy;
    int temp_int[MAXBUF][MAXBUF];
    char temp_string[MAXBUF][MAXBUF];
    float temp_float[MAXBUF][MAXBUF];
    int mol_types;
 
    /* Variable Initialisation */
    System *material;
   
    /* Memory Allocation */
    material = xmalloc (sizeof material);
   
    /* material->temperature = GetFloat ("Specify material temperature (Kelvin): ", 0.0, INF);*/
    material->size = GetInt ("Specify the total number of molceules (Integer): ", 0, 9999999999);
    /* printf ("Please give this system a reference (Max 256 characters): ");
    scanf ("%s", &material->reference); */
   
    material->molecules = xmalloc (material->size * sizeof * material->molecules);
   
    mol_types = GetInt ("Specify the number of different molecule types: ",0 , material->size);
    temp_check = material->size; /* indicates how many molecules left to be allocated */

    dummy = 0; /* a running record of where in the array the molecules have been allocated up to */
   
    for (i=0; i<mol_types; i++) { /* allocate molecule & atomic details */
   
        printf ("\nYou currently have %d molecules left to allocate.", temp_check);
       
        CLS;
        printf ("Molecule %d:\n------------\n\n", (i+1));
        printf ("Specify label for this molecule: "); scanf ("%s", &temp_string[0]);
        temp_int[0][0] = GetInt ("Specify the number of atoms within this molecule: ",0 , 9999999999);

            printf ("mol: %d, i: %d, temp_int: %d", mol_types, i, temp_int[0][0]);
       
        for (k=0; k<temp_int[0][0]; k++) { /*Copy atom details into a temporary array */
           
              printf ("\nAtom %d Proton Number: ", (k+1));
              scanf ("%d", &temp_int[k][1]);
              printf ("Atom %d Neutron Number: ", (k+1));
              scanf ("%d", &temp_int[k][2]);
              printf ("Atom %d Charge: ", (k+1));
              scanf ("%f", &temp_float[k][1]);
              printf ("Atom %d Spin: ", (k+1));
              scanf ("%f", &temp_float[k][2]);
              printf ("Atom %d Symbol: ", (k+1));
              scanf ("%s", temp_string[k+1]);            
        }  

        printf ("\n\nSpecify the number of these molecules within the material (Less than %d): ", (temp_check - mol_types + 1));
        temp = GetInt ("", 0, temp_check);
        temp_check = temp_check - temp;        
       
        for (j=dummy; j<(dummy+temp); j++) {                  

            material->molecules[j] = xmalloc (sizeof material->molecules[j]);
                  printf ("-, ");
            material->molecules[j]->size = temp_int[0][0];
                  printf ("-, ");
            strncpy(material->molecules[j]->reference, temp_string[0], MAXBUF);
                  printf ("-, ");                  
            material->molecules[j]->atoms = xmalloc (material->molecules[j]->size * sizeof *material->molecules[j]->atoms); *IT FAILS ON THIS LINE*
                  printf ("-, ");
            material->molecules[j]->position.x = rand()/(RAND_MAX+1.0);
                  printf ("-, ");
            material->molecules[j]->position.y = rand()/(RAND_MAX+1.0);
                  printf ("-, ");
            material->molecules[j]->position.z = rand()/(RAND_MAX+1.0);
                  printf ("-\n");
                  
           
            for (k=0; k<temp_int[0][0]; k++) {
               
      material->molecules[j]->atoms[k] = xmalloc (sizeof material->molecules[j]->atoms[k]); *OR FAILS ON THIS LINE*
                        printf ("*, ");
                material->molecules[j]->atoms[k]->p = temp_int[k][1];
                                                                printf ("*, ");
      material->molecules[j]->atoms[k]->n = temp_int[k][2];
                        printf ("*, ");
      material->molecules[j]->atoms[k]->charge = temp_float[k][1];
                                                                printf ("*, ");
      material->molecules[j]->atoms[k]->spin = temp_float[k][2];
                                                                printf ("*, ");
      strncpy (material->molecules[j]->atoms[k]->symbol, temp_string[k+1], 3);
                        printf ("*\n");
            }
        }
        dummy = j+1;
   }
   
      return material;
}
       
'xmallox' is a wrapper for malloc where it will automatically check for available memory. 'getint' is a working integer checking input mask. My structures are as follows:

typedef struct tri_dimensional_floats {

    float x;
    float y;
    float z;
} Cartesian;

typedef struct atom_properties {
   
    int p;
    int n;
    char symbol[3];
    float spin;
    float charge;
    Cartesian position;
   
} Atom;

typedef struct molecule_properties {
   
    Atom **atoms;
    Cartesian position;
    char reference[MAXBUF];
    int size;
} Molecule;

typedef struct material_properties {
   
    Molecule **molecules;
    float temperature;
    char reference[MAXBUF];
    int size;
    struct material_properties *next;
} System;


Any help is appreciated as to why it fails on the two specified lines. It compiles fine but the error occurs at run-time.

Cheers,

SolaronAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

grg99Commented:
What is MAXBUF?

>   material = xmalloc (sizeof material);


This can never be correct.... You're asking for memory big enough to hold "material", which is just a pointer.

I think you mean:    material = xmalloc (sizeof (material *) );

or                       :    material = xmalloc ( sizeof ( System )  );
0
grg99Commented:
The error above is probably causing the following lines that store values into  material-->field to wrreck the heap structure,
causing the later mallocs to fail.


Also have xmalloc print out the size of each allocation, and have it test the malloc() result for not NULL.

0
stefan73Commented:
Hi grg99,
> material = xmalloc (sizeof (*material) );


Cheers!

Stefan
0
Get Certified for a Job in Cybersecurity

Want an exciting career in an emerging field? Earn your MS in Cybersecurity and get certified in ethical hacking or computer forensic investigation. WGU’s MSCSIA degree program was designed to meet the most recent U.S. Department of Homeland Security (DHS) and NSA guidelines.  

SolaronAuthor Commented:
I have tried both of those approaches to no success... it halts at exactly the same point. MAXBUF is an integer of 256. i use that just for test purposes. I understood that xmalloc (sizeof xxxxx) is allocating memory to a pointer where as xmalloc (sizeof *xxxxx) allocates pointer memory. Either way, they both cause the same error and i am pretty confident i do not need to bracket the 'sizeof'
0
grg99Commented:
Ok, in your xmalloc, please print out the size.

  It had better be around  272, the apparent size of your "system" struct.

 If it's 4, you're taking the sizeof the wrong thing.

And you *do* need the parentheses in many cases, otherwise sizeof will be parsed incorrectly



0
van_dyCommented:
>> material->molecules = xmalloc (material->size * sizeof * material->molecules);
replace with
  material->molecules = xmalloc (material->size * sizeof (* material->molecules));



>>material->molecules[j] = xmalloc (sizeof material->molecules[j]);
replace with
 material->molecules[j] = xmalloc (sizeof Moleule);


>>material->molecules[j]->atoms = xmalloc (material->molecules[j]->size * sizeof *material->molecules[j]->atoms); *IT FAILS ON THIS LINE*
replace with
material->molecules[j]->atoms = xmalloc (material->molecules[j]->size * sizeof (*material->molecules[j]->atoms)); *IT FAILS ON THIS LINE*


material->molecules[j]->atoms[k] = xmalloc (sizeof material->molecules[j]->atoms[k]); *OR FAILS ON THIS LINE*
replace with
material->molecules[j]->atoms[k] = xmalloc (sizeof Atom); *OR FAILS ON THIS LINE*


hope this helps,
van_dy
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.