[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Arrays of nested structures - cannot allocate memory - HELP

Posted on 2004-11-10
6
Medium Priority
?
225 Views
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);
       
        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,

0
Comment
Question by:Solaron
6 Comments
 
LVL 22

Assisted Solution

by:grg99
grg99 earned 150 total points
ID: 12545926
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
 
LVL 22

Expert Comment

by:grg99
ID: 12545959
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
 
LVL 12

Expert Comment

by:stefan73
ID: 12546037
Hi grg99,
> material = xmalloc (sizeof (*material) );


Cheers!

Stefan
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:Solaron
ID: 12546568
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
 
LVL 22

Expert Comment

by:grg99
ID: 12546730
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
 
LVL 5

Accepted Solution

by:
van_dy earned 225 total points
ID: 12547916
>> 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

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.
Suggested Courses

831 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