# malloc memory corruption (very specific instance of the issue)



## rothn (Dec 10, 2008)

The error occurs in the calloc with this comment next to it: // This command triggers the error on the second iteration of the outermost while loop

The comment is self-explanatory.

notes:
Note that the size of struct menu is 24 bytes.
This program is written in ANSI C (NOT C++).

Please help me here; I spent a day on this bug!

Table of Contents:
-Pertinent Functions
-menus (the file that I am getting interface data from)
-console output (the output from the console from the entire program)

struct vertex
{
int x;
int y;
};
struct menu
{
char *name; // Name of the menu this represents (File, Edit, etc.)
char **children; // Pointer to begining of an array of strings in which the children names are held (New, Open, etc.)
int child_count; // Number of children are in the menu
int menu_width; // Width of the menu
struct vertex origin;
};

char * delete_newline_char (char *str)
{
char *read_ptr = str;
while ((*read_ptr != '\n') && (read_ptr != NULL))
{
read_ptr += sizeof(char);
}
if (*read_ptr == '\n')
{
*read_ptr = '\0';// Change the newline char to a NULL string terminator
}
return str;
}

void draw_interface(Bool for_click_processing) 
{
static struct vertex origin;
static Bool menu_open = 0;
int this_click_on_menu = 0; // Number of menus clicked on (if more than one, is invalid click) 
float xRot = 0.0f, yRot = 0.0f;
float circle_size = 10.0f;
float current_pos = 0.0f;
int i = 0;
int j = 0;
int k = 0;
int chars_written = 0;
int menu_dropdown_offset = 0;
static int menu_number = 0; // Number of the menu clicked on
int desired_menu_raster_pos[2]; // 0 is x, 1 is y (y is currently unused)
int width = render_context.nWinWidth;
int height = render_context.nWinHeight;
float aspect = (float)render_context.nWinWidth/(float)render_context.nWinHeight;
char string_holder[20];
char *szString[MENU_ITEMS] = {"File", "Edit", "View", "Selection", "Tools", "Windows", "Settings", "Documentation", "About"};
char *default_children[DEFAULT_CHILDREN] = {"Padding", "Child 1", "Child 2", "Child 3"};
char *temp; // Used as needed to hold values to be parsed, etc.
struct menu *menus[MENU_ITEMS];
GLfloat raster_position[3];
char *name;
char *child;

FILE *menu_desc;

menu_desc = fopen ("./resource/menu/menus", "r");
if (menu_desc == NULL)
{
printf ("error");
fflush (stdout);
exit (0);
}

i = 0;
while (i < MENU_ITEMS)
{
printf ("fault here? %d", sizeof (struct menu));
fflush (stdout);

menus_ = (struct menu *)malloc (sizeof (struct menu));
name = NULL;
name = (char *)calloc (20, sizeof(char));
fscanf (menu_desc, "%s", name);
name = delete_newline_char (name);// Delete the newline character
menus->name = name;

while (ungetc (getc (menu_desc), menu_desc) != 'c')// Reads the character and puts it back to check if we are done with children
{
child = NULL;
//while (child == NULL)
child = (char *)calloc (20, sizeof(char));
fgets (child, 20, menu_desc);
child = delete_newline_char (child);// Delete the newline character

menus->children[j-1] = child;

printf ("%d", j);
printf ("\n%s\n", menus->children[j-1]);
fflush (stdout);
j += 1;
}
j = 0;

fgets (temp, 4, menu_desc);

printf ("fault is here on the second iteration");
fflush (stdout);
temp = (char *)calloc (4, sizeof(char));// This command triggers the error on the second iteration of the outermost while loop
menus->child_count = j - 1; // The child count is the children read from the file, minus the padding
fgets (temp, 4, menu_desc);

k = atoi (temp);
menus->menu_width = k;

i += 1;
}

fclose (menu_desc);
printf ("%s: %s, %s, %s\n", menus[0]->name, menus[0]->children[0], menus[0]->children[1], menus[0]->children[2]);

#define GL_PI 3.141592 
printf ("%f", aspect);

//switch to drawing 2d with distortion allowed
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
make_static_window (render_context.nWinWidth, render_context.nWinHeight);

//draw the 2D interface here

GLfloat x,y,z,angle; // Storeage for coordinates and angles

// Save matrix state and draw the interface 
glPushMatrix();

glTranslatef (0.0f, (float)render_context.nWinHeight-12.0f, 0.0f);

// Draw the stuff behind the menu bar text

glPushMatrix ();

// Draw the boxes behind the menu items

// Do the drop shadow
glPushMatrix ();

glColor3f(0.0f, 0.0f, 0.0f); // Shadows are black
for (i = 0; i < MENU_ITEMS; ++i)
{
while (j < strlen(menus->name))
{
glRectf (0.0f, 0.0f, 7.0f, 12.0f);
glTranslatef (7.0f, 0.0f, 0.0f);
j++;
}
j = 0;
glTranslatef (12.0f, 0.0f, 0.0f);
}
 glPopMatrix ();

// Do the actual box
glPushMatrix ();

glColor3f(0.270588235f, 0.388235294f, 0.737254902f); // Our box will be a nice blue

glTranslatef (16.0f, 0.0f, 0.0f);
for (i = 0; i < MENU_ITEMS; ++i)
{
while (j < strlen(menus->name))
{
glRectf (-8.0f, -3.0f, 7.0f, 99.0f);
glTranslatef (7.0f, 0.0f, 0.0f);
j++;
}
j = 0;
glTranslatef (12.0f, 0.0f, 0.0f);
}
glPopMatrix ();

glPopMatrix ();

// Restore attributes for normal, prepare to draw the menu bar text
glColor3f(1.0f, 1.0f, 1.0f);

// Now set the screen position for drawing the menu bar
glRasterPos3f(0.0f, 0.0f, 0.0f);

// Save the display list bit
glPushAttrib(GL_LIST_BIT);

// Setup the display list offset
glListBase(uiDListStart - ' ' );

// Now call the appropriate lists for the characters
// in the strings
glRasterPos3f(raster_position[0] + 12.0f, 0.0f, 0.0f);

i = 0;
if (menu_open)
{
printf ("\nmenu %d open with %d children, %d x-origin, and %d y-origin\n", menu_number, menus[menu_number]->child_count, origin.x, origin.y);
while (i < menus[menu_number]->child_count)
{
printf ("%d >= %d\n%d >= %d\n%d <= %d\n%d < %d\n", mouse_clicked_pos[0], origin.x, mouse_clicked_pos[1], 12*i, mouse_clicked_pos[0], origin.x+menus[menu_number]->menu_width, mouse_clicked_pos[1], (i+1)*14+12);

if ((mouse_clicked_pos[0] >= origin.x) && (mouse_clicked_pos[1] >= (i+1)*14) && (mouse_clicked_pos[0] <= origin.x + menus[menu_number]->menu_width) && (mouse_clicked_pos[1] < (i+1)*14+12))
{
printf ("You clicked %s in the %s menu!", menus[menu_number]->children[i+1], menus[menu_number]->name);
}
i += 1;
}
}

menu_open = 0;

for (i = 0; i < MENU_ITEMS; i++)
{
glCallLists(strlen(menus->name), GL_UNSIGNED_BYTE, (GLubyte*)(menus->name));
chars_written += strlen(menus->name) + 1.0f;

if ((mouse_clicked_pos[0] >= raster_position[0]+12.0f) && (mouse_clicked_pos[0] <= (raster_position[0] + 7.0f * strlen(menus->name)+12.0f)) && (mouse_clicked_pos[1] <= 12 ) && (for_click_processing))
{

printf ("\nXORIGIN: %d\nYORIGIN: %d\nMENU#: %d", origin.x, origin.y, menu_number);
glGetFloatv (GL_CURRENT_RASTER_POSITION, raster_position);
desired_menu_raster_pos[0] = raster_position[0];
desired_menu_raster_pos[1] = 0.0f;
this_click_on_menu++;
menu_number = i;
printf ("clicked %s\n", menus->name);
origin.x = mouse_clicked_pos[0];
origin.y = -12;
menu_dropdown_offset = chars_written;
menu_open = 1;

}

printf ("%d, %d\n", mouse_clicked_pos[0], mouse_clicked_pos[1]);

glGetFloatv (GL_CURRENT_RASTER_POSITION, raster_position);

glRasterPos3f(raster_position[0] + 12.0f, 0.0f, 0.0f);
}

if ((for_click_processing) && (this_click_on_menu == 1))
{
i = 0;
printf ("first iteration %s\n", menus[menu_number]->children[1]);
fflush (stdout);
// Draw the menu's background
glColor3f(0.270588235f, 0.388235294f, 0.737254902f); // Our box will be a nice blue
glRectf (mouse_clicked_pos[0]-4.0f, 0.0f, menus[menu_number]->menu_width + mouse_clicked_pos[0] + 4.0f, -13.0f*menus[menu_number]->child_count);
glColor3f(1.0f, 1.0f, 1.0f);

while (i < menus[menu_number]->child_count)
{
glRasterPos3f(mouse_clicked_pos[0], -12.0f*(float)i-12.0f, 0.0f);
printf ("first iteration h\n");
fflush (stdout);
glCallLists(strlen(menus[menu_number]->children[i+1]), GL_UNSIGNED_BYTE, (GLubyte*)(menus[menu_number]->children[i+1]));
i++;

}
}

// Restore the display list bit
glPopAttrib();

glPopMatrix();
glCallList (main_list_start);

//end of drawing 2D stuff

//sets OpenGL back into drawing in 3D 
glColor3f(1.0f, 1.0f, 1.0f); 
glEnable(GL_DEPTH_TEST); 
glEnable(GL_LIGHTING); 
resize_window(render_context.nWinWidth, render_context.nWinHeight);//make the viewport normal again

}

This is the menus file:

File
Padding
Child 1
Child 2
Child 3
c
49
Edit
Padding
Child 1
Child 2
Child 3
c
49
View
Padding
Child 1
Child 2
Child 3
c
49
Selection
Padding
Child 1
Child 2
Child 3
c
49
Tools
Padding
Child 1
Child 2
Child 3
c
49
Windows
Padding
Child 1
Child 2
Child 3
c
49
Settings
Padding
Child 1
Child 2
Child 3
c
49
Documentation
Padding
Child 1
Child 2
Child 3
c
49
About
Padding
Child 1
Child 2
Child 3
c
49

Console Output:

fault here? 240

1
Padding
2
Child 1
3
Child 2
4
Child 3
fault is here on the second iteration*** glibc detected *** ./CADTool: malloc(): memory corruption: 0x090135a8 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7d29276]
/lib/tls/i686/cmov/libc.so.6(__libc_calloc+0xef)[0xb7d2a6ef]
/usr/lib/libGL.so.1[0xb7f26314]
./CADTool[0x8049826]
./CADTool[0x8049979]
./CADTool(_init+0x1c4)[0x8049d73]
./CADTool[0x804ae43]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7ccd775]
./CADTool[0x8049691]
======= Memory map: ========
08048000-0804d000 r-xp 00000000 08:05 3680429 /home/rothn/VGP/CADTool
0804d000-0804e000 r--p 00004000 08:05 3680429 /home/rothn/VGP/CADTool
0804e000-0804f000 rw-p 00005000 08:05 3680429 /home/rothn/VGP/CADTool
08f6d000-0903b000 rw-p 08f6d000 00:00 0 [heap]
b6500000-b6521000 rw-p b6500000 00:00 0 
b6521000-b6600000 ---p b6521000 00:00 0 
b66a9000-b66ea000 rw-p b66a9000 00:00 0 
b66ea000-b66f2000 r-xp 00000000 08:05 2385500 /usr/lib/libXrender.so.1.3.0
b66f2000-b66f3000 r--p 00007000 08:05 2385500 /usr/lib/libXrender.so.1.3.0
b66f3000-b66f4000 rw-p 00008000 08:05 2385500 /usr/lib/libXrender.so.1.3.0
b66f4000-b66fc000 r-xp 00000000 08:05 2385470 /usr/lib/libXcursor.so.1.0.2
b66fc000-b66fd000 rw-p 00007000 08:05 2385470 /usr/lib/libXcursor.so.1.0.2
b6717000-b6917000 rw-s 2a906000 00:0f 7904 /dev/nvidia0
b6917000-b6a17000 rw-s 2a8d1000 00:0f 7904 /dev/nvidia0
b6a17000-b6a18000 rw-s e2c08000 00:0f 7904 /dev/nvidia0
b6a18000-b6a58000 rw-s 2a820000 00:0f 7904 /dev/nvidia0
b6a58000-b6a78000 rw-s 330f0000 00:0f 7904 /dev/nvidia0
b6a78000-b6b4b000 rw-p b6a78000 00:00 0 
b6b4b000-b6b95000 rw-p 00000000 00:0f 765 /dev/zero
b6b95000-b6bc9000 rw-p b6b95000 00:00 0 
b6bc9000-b6bea000 rw-s 00000000 00:09 0 /SYSV00000000 (deleted)
b6bea000-b6bec000 rw-p b6bea000 00:00 0 
b6bec000-b6bef000 r-xp 00000000 08:05 2990493 /lib/libuuid.so.1.2
b6bef000-b6bf0000 r--p 00002000 08:05 2990493 /lib/libuuid.so.1.2
b6bf0000-b6bf1000 rw-p 00003000 08:05 2990493 /lib/libuuid.so.1.2
b6bf1000-b6bf5000 r-xp 00000000 08:05 2385474 /usr/lib/libXdmcp.so.6.0.0
b6bf5000-b6bf6000 rw-p 00003000 08:05 2385474 /usr/lib/libXdmcp.so.6.0.0
b6bf6000-b6bf7000 rw-p b6bf6000 00:00 0 
b6bf7000-b6bf9000 r-xp 00000000 08:05 2385383 /usr/lib/libXau.so.6.0.0
b6bf9000-b6bfa000 r--p 00001000 08:05 2385383 /usr/lib/libXau.so.6.0.0
b6bfa000-b6bfb000 rw-p 00002000 08:05 2385383 /usr/lib/libXau.so.6.0.0
b6bfb000-b6c08000 r-xp 00000000 08:05 2990101 /lib/libgcc_s.so.1
b6c08000-b6c09000 r--p 0000c000 08:05 2990101 /lib/libgcc_s.so.1
b6c09000-b6c0a000 rw-p 0000d000 08:05 2990101 /lib/libgcc_s.so.1
b6c0a000-b6cee000 r-xp 00000000 08:05 2384214 /usr/lib/libstdc++.so.6.0.10
b6cee000-b6cf2000 r--p 000e3000 08:05 2384214 /usr/lib/libstdc++.so.6.0.10
b6cf2000-b6cf3000 rw-p 000e7000 08:05 2384214 /usr/lib/libstdc++.so.6.0.10
b6cf3000-b6cf9000 rw-p b6cf3000 00:00 0 
b6cf9000-b6cfa000 r-xp 00000000 08:05 2876566 /usr/lib/tls/libnvidia-tls.so.180.44
b6cfa000-b6cfb000 rw-p 00000000 08:05 2876566 /usr/lib/tls/libnvidia-tls.so.180.44
b6cfb000-b7a15000 r-xp 00000000 08:05 2387652 /usr/lib/libGLcore.so.180.44
b7a15000-b7c07000 rwxp 00d19000 08:05 2387652 /usr/lib/libGLcore.so.180.44
b7c07000-b7c13000 rwxp b7c07000 00:00 0 
b7c13000-b7c28000 r-xp 00000000 08:05 2385422 /usr/lib/libICE.so.6.3.0
b7c28000-b7c29000 rw-p 00014000 08:05 2385422 /usr/lib/libICE.so.6.3.0
b7c29000-b7c2c000 rw-p b7c29000 00:00 0 
b7c2c000-b7c33000 r-xp 00000000 08:05 2384006 /usr/lib/libSM.so.6.0.0
b7c33000-b7c34000 r--p 00006000 08:05 2384006 /usr/lib/libSM.so.6.0.0
b7c34000-b7c35000 rw-p 00007000 08:05 2384006 /usr/lib/libSM.so.6.0.0
b7c35000-b7c84000 r-xp 00000000 08:05 2384131 /usr/lib/libXt.so.6.0.0
b7c84000-b7c85000 r--p 0004f000 08:05 2384131 /usr/lib/libXt.so.6.0.0
b7c85000-b7c88000 rw-p 00050000 08:05 2384131 /usr/lib/libXt.so.6.0.0
b7c88000-b7c96000 r-xp 00000000 08:05 2384013 /usr/lib/libXext.so.6.4.0
b7c96000-b7c97000 r--p 0000d000 08:05 2384013 /usr/lib/libXext.so.6.4.0
b7c97000-b7c98000 rw-p 0000e000 08:05 2384013 /usr/lib/libXext.so.6.4.0
b7c98000-b7c9a000 r-xp 00000000 08:05 3007299 /lib/tls/i686/cmov/libdl-2.9.so
b7c9a000-b7c9b000 r--p 00001000 08:05 3007299 /lib/tls/i686/cmov/libdl-2.9.so
b7c9b000-b7c9c000 rw-p 00002000 08:05 3007299 /lib/tls/i686/cmov/libdl-2.9.so
b7c9c000-b7cb4000 r-xp 00000000 08:05 2385392 /usr/lib/libxcb.so.1.1.0
b7cb4000-b7cb5000 r--p 00017000 08:05 2385392 /usr/lib/libxcb.so.1.1.0
b7cb5000-b7cb6000 rw-p 00018000 08:05 2385392 /usr/lib/libxcb.so.1.1.0
b7cb6000-b7cb7000 rw-p b7cb6000 00:00 0 
b7cb7000-b7e13000 r-xp 00000000 08:05 3007296 /lib/tls/i686/cmov/libc-2.9.so
b7e13000-b7e14000 ---p 0015c000 08:05 3007296 /lib/tls/i686/cmov/libc-2.9.so
b7e14000-b7e16000 r--p 0015c000 08:05 3007296 /lib/tls/i686/cmov/libc-2.9.so
b7e16000-b7e17000 rw-p 0015e000 08:05 3007296 /lib/tls/i686/cmov/libc-2.9.so
b7e17000-b7e1a000 rw-p b7e17000 00:00 0 
b7e1a000-b7e48000 r-xp 00000000 08:05 2384177 /usr/lib/libglut.so.3.8.0
b7e48000-b7e4a000 r--p 0002d000 08:05 2384177 /usr/lib/libglut.so.3.8.0
b7e4a000-b7e4d000 rw-p 0002f000 08:05 2384177 /usr/lib/libglut.so.3.8.0
b7e4d000-b7e71000 r-xp 00000000 08:05 3007300 /lib/tls/i686/cmov/libm-2.9.so
b7e71000-b7e72000 r--p 00023000 08:05 3007300 /lib/tls/i686/cmov/libm-2.9.so
b7e72000-b7e73000 rw-p 00024000 08:05 3007300 /lib/tls/i686/cmov/libm-2.9.so
b7e73000-b7ee2000 r-xp 00000000 08:05 2385160 /usr/lib/libGLU.so.1.3.070300
b7ee2000-b7ee3000 ---p 0006f000 08:05 2385160 /usr/lib/libGLU.so.1.3.070300
b7ee3000-b7ee4000 r--p 0006f000 08:05 2385160 /usr/lib/libGLU.so.1.3.070300
b7ee4000-b7ee5000 rw-p 00070000 08:05 2385160 /usr/lib/libGLU.so.1.3.070300
b7ee5000-b7f72000 r-xp 00000000 08:05 2387651 /usr/lib/libGL.so.180.44
b7f72000-b7f90000 rwxp 0008d000 08:05 2387651 /usr/lib/libGL.so.180.44
b7f90000-b7f9f000 rwxp b7f90000 00:00 0 
b7f9f000-b7fb4000 r-xp 00000000 08:05 2385490 /usr/lib/libXmu.so.6.2.0
b7fb4000-b7fb5000 rw-p 00015000 08:05 2385490 /usr/lib/libXmu.so.6.2.0
b7fb5000-b7fb6000 rw-p b7fb5000 00:00 0 
b7fb6000-b7fbe000 r-xp 00000000 08:05 2384523 /usr/lib/libXi.so.6.0.0
b7fbe000-b7fbf000 r--p 00007000 08:05 2384523 /usr/lib/libXi.so.6.0.0
b7fbf000-b7fc0000 rw-p 00008000 08:05 2384523 /usr/lib/libXi.so.6.0.0
b7fc0000-b80aa000 r-xp 00000000 08:05 2385388 /usr/lib/libX11.so.6.2.0
b80aa000-b80ab000 ---p 000ea000 08:05 2385388 /usr/lib/libX11.so.6.2.0
b80ab000-b80ac000 r--p 000ea000 08:05 2385388 /usr/lib/libX11.so.6.2.0
b80ac000-b80ae000 rw-p 000eb000 08:05 2385388 /usr/lib/libX11.so.6.2.0
b80ae000-b80af000 rw-p b80ae000 00:00 0 
b80b2000-b80b3000 rw-p b80b2000 00:00 0 
b80b3000-b80b7000 r-xp 00000000 08:05 2385480 /usr/lib/libXfixes.so.3.1.0
b80b7000-b80b8000 rw-p 00003000 08:05 2385480 /usr/lib/libXfixes.so.3.1.0
b80b8000-b80bc000 rw-s 2a972000 00:0f 7904 /dev/nvidia0
b80bc000-b80c0000 rw-s 33365000 00:0f 7904 /dev/nvidia0
b80c0000-b80c1000 rw-s d1221000 00:0f 7904 /dev/nvidia0
b80c1000-b80c2000 rw-s 2b645000 00:0f 7904 /dev/nvidia0
b80c2000-b80c3000 rw-s 2a8a7000 00:0f 7904 /dev/nvidia0
b80c3000-b80c4000 rw-s e2641000 00:0f 7904 /dev/nvidia0
b80c4000-b80c5000 rw-s 34ecb000 00:0f 7904 /dev/nvidia0
b80c5000-b80c6000 rw-s e2060000 00:0f 7904 /dev/nvidia0
b80c6000-b80c7000 rw-p b80c6000 00:00 0 
b80c7000-b80c9000 rwxp 00000000 00:0f 765 /dev/zero
b80c9000-b80cb000 rw-p b80c9000 00:00 0 
b80cb000-b80cc000 r-xp b80cb000 00:00 0 [vdso]
b80cc000-b80e8000 r-xp 00000000 08:05 2990142 /lib/ld-2.9.so
b80e8000-b80e9000 r--p 0001b000 08:05 2990142 /lib/ld-2.9.so
b80e9000-b80ea000 rw-p 0001c000 08:05 2990142 /lib/ld-2.9.so
bfacb000-bfae7000 rwxp bffe2000 00:00 0 [stack]
bfae7000-bfae9000 rw-p bfffe000 00:00 0 
Aborted_


----------



## lotuseclat79 (Sep 12, 2003)

Do you have a symbolic debugger in your development environment? 

If not, consider gcc and gdb which are free. That is how I would debug the code, and if you follow up and do that, you will build a valuable skill that will enable you to not take so much time debugging your code.

-- Tom

P.S. Never, ever use any computer language compiler without a symbolic debugger - i.e. the difference is:
With a symbolic debugger, development becomes productive - without non-productive!


----------



## rothn (Dec 10, 2008)

I used GDB; when I removed the calloc to re-initialize the character pointer temp, the error was moved to the malloc at the top of my for loop that allocates the next element of the array of pointers to struct menu. Please help me here. Should I include a debuggable binary?


----------



## lotuseclat79 (Sep 12, 2003)

Hi rothn,

Do not upload a debuggable binary. Have you single stepped you way through the program, and set a breakpoint at reasonable statements where it is possible that the program is messing up as programmed? If not, do it - it will teach you more than I can advise you. Also, look up the doc on the malloc and calloc calls to make sure you understand what you have coded.

It would help anyone if you included a program specification of what it was your program as you coded it intended it to do. I realize most programmers tend to code before they can explicitly write any documentation for what they intend code to do, but you have to understand the difference between design and implementation (which is what coding is). A specification helps the implementor implement the code as the designer intends and forms a contract between a design and an implementation. You should get in the habit of attempting to write a design document before you code an implementation of an idea - I know, its hard to do, especially when someone becomes very good at programming and proceeds to do design-prototyping as they work daily.

But, give it a try, and you will make less mistakes in your coding and be able to catch problems like this with the debugger, or with assert statements that keep your code out of trouble. When all is said and done after this problem is fixed, make sure you write it up as a lesson learned, and document the errant assumption in the code that was causing the error. You'll be glad you did later on when you see a future opportunity to avoid the same mistake and can assure you do not repeat it in the future.

-- Tom


----------



## rothn (Dec 10, 2008)

What I wrote is a loop to load menu data from a file into a structure for each menu element. Malloc allocates one of those structures for one element of the array of pointers each time we need to load another menu item. The entire program is a CAD tool, and I will not include my flow chart (made in Visio under Wine windows emulator) because it is irrelevant, and stealing my program will be simple with it (merely write out what the chart says to do). Unfortunately, the menu part isn't quite that simple. The program errors out after the memory allocation following the malloc to allocate the big structure for the currently being loaded menu item.


----------

