Submitted by Anonymous on Mon, 04/22/2002 - 10:39. Developers
High All,
I`m not developping under Motif for a while and have problems with a program that I developed. This program monitors the activity of a financial application. There is a main screen in
which I create XmList widgets which I first empty using XmListDeleteAllItems and fill using XmListAddItem or XtSetValues(...). There is a timer which calls the empty/fill list function every 30 or 60 seconds.
The programm is running under HP/UX 10.
When I run the program and make a ps -efl | grep myprogram, the SZ column always grows meaning that my program consumes more and more memory at every refresh. I wait wait for 24 hours, the program stops with a core of hundreds megabytes, filling the filesystem ...
I searched for informations on freeing widgets memory, but don`t find anything. Please does someone can help me (URL or a book on this subject or better an example).
Bellow an excerpt of my empty/fill function.
/* --- Empty the list */
XmListDeleteAllItems( mon.frameFilesList[ffl_import] );
strcpy( importDirPath, (const char *) getenv( MC_IMPORT ) );
nFiles = scandir( importDirPath, &nameList, mc_generic_select, alphasort );
/* --- Allocate memory liste */
string = (XmString *) XtMalloc( sizeof(XmString) * nFiles );
list = nameList;
for ( i=0; i {
sprintf( fileName, "%s/%s", getenv( MC_IMPORT ), (*list)->d_name );
sprintf( line, "%s %s", mc_get_file_dtc( fileName ), (*list)->d_name );
string[i] = XmStringCreate( line, XmSTRING_DEFAULT_CHARSET );
*list++;
}
/* --- Free the scandir list */
list = nameList;
for ( i=0; i free(*list);
free( nameList );
/* --- Sort the list */
qsort( (void *) string, (size_t) nFiles, (size_t) sizeof(XmString), mc_compound_string_compare );
i = 0;
XtSetArg( argsw[i], XmNitems, string ); i++;
XtSetArg( argsw[i], XmNitemCount, nFiles ); i++;
XtSetValues( mon.frameFilesList[ffl_import], argsw, i );
for ( i=0; i XmStringFree( string[i] );
XtFree( string );
Doesn`t this code
for ( i=0; i free(*list);
just repeatedly free nameList[0]? I think you want "free(list[i])" there, or you need to increment list in this loop.
A good memory-tracer such as Purify or AcquaProva will find this
sort of problem immediately after the first run.
Hi dbl,
Many thanks for your help, your suggestion was right, the part of code you pointed was really bad ...
And I found another bug in my program, I forgot to free a structure filled by a scandir in a directory containing many files ... this was another part of my problem.
If you read this, I have another question
if I create a dialog using form = XmCreateFormDialog(..) then I create childs using XtVaCreateManagedWidget( "frame", xmFrameWidgetClass, form, XmNshadowType, XmSHADOW_ETCHED_IN, NULL ) ... and then buttons and lists, if I want to free the memory allocated by those windows and child, do I only need to call XtDestroyWidget( form ) which deletes and frees parent and all childrens or do I need to delete parent and all childs ???
In my experience, I only make a XtDestroyWidget(form) with form containing frames, buttons, lists but it seems not to free the memory allocated (I wait for 10 minutes looked as the ps -efl result but the column SZ is always the same.
Widget destruction is recursive -- you destroy the widget at the root (top-most parent) and Xt destroys all other widgets and their associated resouces. Perhaps you allocated other memory, such as for compound strings, and did not free that memory.
In any case, "ps" isn`t a great tool for figuring out this sort of thing. There are several commercial products that can help you. On the cheap, you can recompile Xt with -DXT_TRACE_MEMORY to get some assistance. There are also free packages such as dmalloc that you can use to trace memory allocations.
Hi, Just passing through. I`m agree with dbl. But I`m concerned with the value of the pointer in variable `list`. Maybe you mistyped the message?
In the `for` loop that frees elements in nameList (accessed by *list) the pointer is not incremented. So you would be freeing the same location nFiles times.
list = nameList;
for ( i=0; i {
sprintf( fileName, "%s/%s", getenv( MC_IMPORT ), (*list)->d_name );
sprintf( line, "%s %s", mc_get_file_dtc( fileName ), (*list)->d_name );
string[i] = XmStringCreate( line, XmSTRING_DEFAULT_CHARSET );
*list++;
}
/* --- Free the scandir list */
list = nameList;
for ( i=0; i free(*list);
/* free( * list ++ ) ; */
free( nameList );