Arrays of nested structures - cannot allocate memory - HELP

Posted on 2004-11-10
Last Modified: 2010-04-15
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);
        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.


Question by:Solaron
    LVL 22

    Assisted Solution

    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 )  );
    LVL 22

    Expert Comment

    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.

    LVL 12

    Expert Comment

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



    Author Comment

    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'
    LVL 22

    Expert Comment

    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

    LVL 5

    Accepted Solution

    >> 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,

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How to run any project with ease

    Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
    - Combine task lists, docs, spreadsheets, and chat in one
    - View and edit from mobile/offline
    - Cut down on emails

    Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
    This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
    The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
    The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

    737 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    20 Experts available now in Live!

    Get 1:1 Help Now