1
我想了解爲什麼下面的程序正在泄漏內存。當我通過使用命令more /proc/<pid>/smaps
查看堆大小時,我可以看到堆只在增長。看來XtDestroyWidget並沒有真正釋放內存。如果有人能告訴我爲什麼會發生這種情況,並告訴我重新創建小部件的正確方法,我將非常感激。 在此先感謝!X工具包:重新創建小部件時堆正在增長
/* Compile on Solaris: cc widgets_mem.c -lXm -lXt -lX11 */
/* Compile on Linux: gcc -m32 widgets_mem.c -lXm -lXt -lX11 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysymdef.h>
#include <Xm/MainW.h>
#include <Xm/PushB.h>
#include <Xm/Form.h>
Widget toplevel;
Widget w_main;
Widget w_bb;
Widget w_button = NULL;
Window root_win;
XtAppContext app;
int screen_number;
Display *display = NULL;
void recreateWidgets()
{
printf ("recreating widgets\n");
XtDestroyWidget (w_button);
w_button = XtVaCreateManagedWidget (
"button",
xmPushButtonWidgetClass, w_bb,
XmNfillOnArm, False,
XmNhighlightThickness, 0,
XmNborderWidth, 1,
XmNmarginTop, 1,
XmNmarginWidth, 2,
XmNmarginHeight, 0,
XmNwidth, 20,
XmNheight, 10,
XmNrecomputeSize, False,
XmNalignment, XmALIGNMENT_CENTER,
NULL);
}
void main (int argc, char **argv)
{
XEvent event;
toplevel = XtVaAppInitialize (&app, "Mem leak test",
NULL, 0, &argc, argv, NULL, NULL);
display = XtDisplay (toplevel);
screen_number = DefaultScreen (display);
root_win = RootWindow (display, screen_number);
w_main = XtVaCreatePopupShell (
"main",
topLevelShellWidgetClass, toplevel,
XmNgeometry, "-0+0",
XmNborderWidth, 0,
XmNshadowThickness, 0,
XmNminWidth, 1,
XmNmwmDecorations, 0,
XmNmwmFunctions, 0,
XmNwidth, 600,
XmNheight, 200,
NULL);
w_bb = XtVaCreateManagedWidget (
"",
xmBulletinBoardWidgetClass, w_main,
XmNborderWidth, 4,
XmNshadowThickness, 0,
XmNmarginWidth, 0,
XmNmarginHeight, 0,
XmNx, 0,
XmNy, 0,
XmNwidth, 500,
XmNheight, 100,
NULL);
w_button = XtVaCreateManagedWidget (
"button",
xmPushButtonWidgetClass, w_bb,
XmNfillOnArm, False,
XmNhighlightThickness, 0,
XmNborderWidth, 1,
XmNmarginTop, 1,
XmNmarginWidth, 2,
XmNmarginHeight, 0,
XmNwidth, 20,
XmNheight, 10,
XmNrecomputeSize, False,
XmNalignment, XmALIGNMENT_CENTER,
NULL);
XtPopup (w_main, XtGrabNone);
while (1)
{
XtAppNextEvent (app, &event);
if (event.type == ButtonPress)
{
printf ("Button pressed, recreating widgets\n");
recreateWidgets();
}
}
}
請注意,當內存被釋放時,它不會返回到o/s;它由內存管理系統保存以供重用。如果你釋放一個小部件,那麼它使用的空間可能會被創建的下一個小部件使用。所以,它可能是因爲沒有問題。 OTOH,如果你的程序最終因內存不足而崩潰,你確實有泄漏需要修復。 –
在Linux和Solaris上,void main()都是無條件錯誤的。 main()的返回類型是int。只有在Windows上,您才能從中獲得豁免權,而您不在Windows上。現代中間編譯器會抱怨這一點。您沒有使用足夠的編譯警告。 –
如果你認爲你的程序在泄漏內存,我建議你使用[valgrind](http://valgrind.org/),[dmalloc](http://dmalloc.com/)或[efence](http ://elinux.org/Electric_Fence)。 – Bass