C++ Memory leak detection
@Hero
Question?
2
 What does “memory leak” mean ?
 How is memory structure ?
 What does its consequences ?
 Why does “memory leak” happen ?
 How to detect and solve?
What does “memory leak” mean ?
First, How is memory structure ?
3
How is memory structure ?
STACK vs HEAP
4
Run-time storage
5
 Code segment:
• where the compiled program sits in
memory
 Global area:
• Initialized data segment: store e global,
static and constant data
• Uninitialized data segment
 Stack segment:
• where parameters and local variables are
allocated
 Heap segment:
• where dynamically allocated variables are
allocated
Text segment
(Code segment)
Stack segment
Heap Segment
Data segment
MIPS
Stack
6
 Where parameters and
local variables are
allocated
 Limited size  Stack
overflow
 Memory use in stack is
temporary and auto
release
 Fast processing/low size
Parameters
Return Address
where to begin execution
when function exits
Dynamic link
pointer to caller's stack
frame
Static link
pointer to lexical parent
(for nested functions)
Return value
Local variables
“Concept” Stack frame
Text segment
(Code segment)
Stack frame
Heap Segment
Data segment
Stack frame
Heap
7
 Large pool of memory
 Dynamic allocation
 Stays allocated until
specifically deallocated 
leak !
 Must be accessed through a
pointer
 Large arrays, structures, or
classes should be stored
Heap  why?
 Large & dynamic
Parameters
Return Address
where to begin execution
when function exits
Dynamic link
pointer to caller's stack
frame
Static link
pointer to lexical parent
(for nested functions)
Return value
Local variables
“Concept” Stack frame
Text segment
(Code segment)
Stack frame
Heap Segment
Data segment
Stack frame
Heap vs Stack
8
 int _array[10];  stored in stack
Stack
_array
int *_array = new int[n]
• Pointer _array is stored in Stack
• Data of array is stored in Heap
_array
0x00FF
Stack
10
Heap
0x00FF
0x000
5
Value of:
● _array : address where int “point” into in heap (0x00FF)
● (*_array): value at it's address on heap (10)
● (&_array): address of the memory which used for stored pointer
_array in stack (0x0005)
Always
stored in
stack ?
Any chance to
store _array in
heap?
FAQ
9
 Why we use
Classname *Obj = new Classname();
 instead of
Classname Obj;
Memory leak overview
10
What does memory leaking mean?
11
 Definition:
 Particular type of unused memory, unable to release
 Common:
 Refer to any unwanted increase in memory usage
 Different from memory fragmentation
* for heap memory
void Leak()
{
int *A = new int[1000];
// some code here
// ...
// without delete A
//
return;
}
4000 bytes
Return without free A →
Leak
What does its consequences ?
12
 Application gets slow fps
 Application is crashed
 Device has been freeze, restarted
Why does “memory leak”
happen?
First, Let's see some examples
13
Example 0
14
 Forget to release resources
 No GC mechanic supported
Button is
pressed
Save current floor
On target
floor ?
Wait until lift is idle
Go to required
floor
Release memory used to
save current floor
True
Finished Memory
Leaking
here
void Fa()
{
}
void Fb()
{}
void Leak()
{
int *a = new int[10];
Fa();
Fb();
return;
}
void main()
{
Leak();
}
C/C++ Example 1
15
 Leak memory caused
by lacking of release
dynamic memory
…
delete a[];
return;
Solution
Leak !
C/C++ Example 2
16
 Allocation a series,
delete only one unit
Leak !
for (int i = 0; i < 10; i++)
{
delete list[i];
}
delete list;
Solution
void leak()
{
int **list = new int*[10];
for (int i = 0; i < 10; i++)
{
list[i] = new int;
}
delete list;
return;
}
C/C++ Example 3
17
Leak memory when
using pointer-return-
type
delete []str;
Avoid to call directly GenString()
Solution
char* GenString()
{
char *a = new char[10];
a[9] = '0';
return a;
}
void Leak()
{
char *str = GenString();
printf("%sn", str);
printf("%sn", GenString());
}
#include <cstdio>
void Foo()
{
int* a = new int[100];
a = new int[1000];
}
void Foo1()
{
int* a = new int[100];
int* b = new int[1000];
a = b;
}
C/C++ Example 4
18
Leak memory because of misunderstanding “=”
operator in C++
Stack
Heap
A
LEAK!
Leak!
C/C++ Example 5
19
void main()
{
Classname *A = new A();
...
...
//free A
A = NULL;
}
Misunderstand how to free memory
method in C/C++
Stack
Heap
A
NULL
LEAK!
 Keep in mind we are using C/C++
 Use MACRO for safe deallocating
#define SAFE_DEL(a) {if(a){delele a;a = 0;}}
Solution
C/C++ Example 6 - STL
20
class Element
{
int ID;
public:
Element(int id)
{
printf("Created %d at 0x%xn", id, this);
ID = id;
}
~Element()
{
printf("Destroy %d at 0x%xn", ID, this);
}
};
int main()
{
list<Element*> m_List;
Element *e0 = new Element(0);
Element *e1 = new Element(1);
//add to list
m_List.push_back(e0); m_List.push_back(e1);
//clear list
printf("-----Before clear-----n");
m_List.clear();
printf("-----After clear-----n");
return 0;
}
Created 0 addr 0xa719c0
Created 1 addr 0xa81a18
-----Before clear-----
-----After clear-----
Command prompt
Memory
leak here
list
Item 0
Item 1
e0
e1
C/C++ Example 6 – STL (cont.)
21
int main()
{
list<Element*> m_List;
Element *e0 = new Element(0);
Element *e1 = new Element(1);
//add to list
m_List.push_back(e0);
m_List.push_back(e1);
//clear list
printf("-----Before clear-----n");
list <Element*>::iterator i;
for (i = m_List.begin(); i != m_List.end(); i++)
{
delete *i;
}
m_List.clear();
printf("-----After clear-----n");
return 0;
}
Free data of each
element pointer
Created 0 addr 0xb61a28
Created 1 addr 0xb71a70
-----Before clear-----
Destroy 0 addr 0xb61a28
Destroy 1 addr 0xb71a70
-----After clear-----
Command prompt
Example 7
22
class CB {
public:
CB(){
m_iVal = 0;
}
~CB(){}
int m_iVal;
};
class CA {
public:
CA(){
m_pB = 0;
}
~CA(){
delete m_pB;
m_pB = 0;
}
CB *m_pB;
};
int main()
{
CB *B = new CB;
CA *A = new CA();
A->m_pB = B;
delete(A);
printf("%d", B->m_iVal);
}
B
A
m_pB
Access violation
reading location
….
Try to
remove
delete m_pB
Example 7 (cont.)
23
class CB {
public:
CB(){
m_iVal = 0;
}
~CB(){}
int m_iVal;
};
class CA {
public:
CA(){
m_pB = 0;
}
~CA(){
delete m_pB;
m_pB = 0;
}
CB *m_pB;
};
int main()
{
CA *A = new CA();
A->m_pB = new CB()
delete(A);
}
A
m_pB
Leak
Delete or not?
Use manual dealocate
m_pB
Solution
24
C/C++ Example 8
class cA()
{
public :
cA() {m_pdata = new int[100];}
virtual ~cA() {delete[]
m_pdata;}
int *m_pdata;
};
class cB: public cA()
{
public
cB():cA() {m_pdata2 = new
int[100];}
~cB() {delete []m_pdata2;}
int *m_pdata2;
}
void main()
{
cA *A = new cB();
delete A;
}
Memory leak caused by
misunderstanding finalization method
Without “virtual”, in this case,
m_pdata is not deleted → leak
ALWAYS use virtual for
finalization methods
Solution
C/C++ Example 9
25
Using new vs free.
Destructor will be NOT
invoked after free
class MyClass
{
public
MyClass()
{
m_pdata2 = new int[100];
}
~ MyClass()
{
delete []m_pdata2;
}
int *m_pdata2;
}
void main()
{
MyClass* p = new MyClass();
free(p);
}
Leak here
What are reasons of memory leak?
26
 Forget/ misunderstand C/C++ mechanism
 Out-of-Control (logic)
Current Solutions
27
 For “Forget/ misunderstand C/C++ mechanism”
 Semi-automatic memory management
 Reference Counting
 Automatic memory management
 Tracing Garbage Collection (GC): Java , C #
 No GC mechanic for C/C++
Reference Counter: Good or bad ?
28
 Reference counter:
Simple method for
memory conflict
resolution
 Algorithms:
• Increase counter when
use as reference
• Decrease when release
• Delete memory of
counter is zero
class IShareMem
{
public:
IShareMem():m_iRefCounter(1){}
virtual ~IShareMem(){}
static
IShareMem* SetReference(IShareMem* src)
{
src->m_iRefCounter++;
return src;
}
void Release()
{
m_iRefCounter--;
if (m_iRefCounter <= 0)
{
delete this;
}
}
private:
int m_iRefCounter;
};
Reference Counter: Good or bad ?
29
 Good:
 Avoid conflict in memory usage. (See example no.7)
 Bad:
 Cause memory leak if user forget “release”
 Hard to detect memory leak.
 Sometimes CAN NOT DETECT LEAK by tool (leak but
not really leak)
Current Solutions - Disadvantage
30
 Garbage collectors generally can do nothing about
logical memory leaks
0
1
2
n
..
.
Alloc
Alloc
Alloc
Alloc
Which is really needed?A
B
D
E
Z
Do I alloc some-
where without
release?
Somethings else
is pointed
to an object
C/C++
How to avoid, detect?
31
 Rule:
 Remember to release dynamic data (pointer)  HARD
 Keep our resource in well controlled  TOO HARD
 Detect
 By phenomenon on device ?  not exactly
 By review source ?  TOO HARD
 By tool
 VC++ memory leak debugging
 External tool
 Cannot detect some cases.
C/C++
How to solve?
32
 Easy to detect, but hard to solve
 Experience
 Organize source and keep it in control
 Such as a document about resource ?!?
Applicatio
n
Leak log
data
Detect Memory leak
Leak
InformationAnalysis
Experience
Knowledge
Fix and test
Detect Memory Leak
33
Memory leak – quick detection
34
 Windows: use task manager / process tab
 Android:
adb shell top -m <number_of_record>
See VSS, RSS
Use Visual studio supported function
35
 Use __CrtDumpMemoryLeaks
 Advantage
 Easy to use
 Fully report about leak when application completed
 Free
 Disadvantage
 Cannot detect run-time
 Fail if application Crashed
 Presentation:
 Manually coding by user
 Use some lib such as VLD
Debug in Visual studio
36
VLD Tool
37
 http://www.codeproject.com/KB/applications/visualleakdetector.aspx
 http://vld.codeplex.com/
 Include vld.h in source
 Add vld.lib
#include "vld.h"
#pragma comment(lib, "vld.lib")
VLD Tool
38
 After finish application normally, memory leak
information will be displayed in output
WARNING: Visual Leak Detector detected memory leaks!
---------- Block 3 at 0x006F4F98: 12 bytes ----------
Call Stack:
c:usersricky.ngkdesktoptestleaktestleakmain.cpp (81): TestLeak.exe!Init + 0x7 bytes
c:usersricky.ngkdesktoptestleaktestleakmain.cpp (108): TestLeak.exe!main
f:ddvctoolscrt_bldself_x86crtsrccrtexe.c (586): TestLeak.exe!__tmainCRTStartup + 0x19 bytes
f:ddvctoolscrt_bldself_x86crtsrccrtexe.c (403): TestLeak.exe!mainCRTStartup
0x76BBED6C (File and line number not available): kernel32.dll!BaseThreadInitThunk + 0x12 bytes
0x772237F5 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0xEF bytes
0x772237C8 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0xC2 bytes
Data:
74 A7 DF 00 01 00 00 00 20 60 6F 00 t....... .`o.....
Double click the stack to navigate to source
VLD Tool
 Like any leak detect tools, shows where memory was
allocated without free
 User have to analyst to find real reason
Debug memory leak run-time
40
 Use some tool, such as:
 Glow code: http://www.glowcode.com/
 Memory validator: http://www.softwareverify.com/cpp-
memory.php
 Advantage
 Runtime checking
 Nice Interface
 Disadvantage
 Not free
 Not easy to use. Need tutorial
 Note: Those tool cannot working well with VLD
The end!
Thanks for your attention
Appendix – Top ten excuses for memory leak
 A little memory leak is no big thing
 Nobody will ever find out
 Complex programs always have memory leak
 My application Framework is too entangled
 The memory leak is in the operation system
 The memory leak is in my third party tools
 Product development cycles are too fast
 It’s hard to get good programmer today
 Leaks and bugs are the price you pay for GUI
 Everything else leaks, why shouldn’t mine?
http://www.troubleshooters.com/codecorn/memoryleak.htm

C++ memory leak detection

  • 1.
    C++ Memory leakdetection @Hero
  • 2.
    Question? 2  What does“memory leak” mean ?  How is memory structure ?  What does its consequences ?  Why does “memory leak” happen ?  How to detect and solve?
  • 3.
    What does “memoryleak” mean ? First, How is memory structure ? 3
  • 4.
    How is memorystructure ? STACK vs HEAP 4
  • 5.
    Run-time storage 5  Codesegment: • where the compiled program sits in memory  Global area: • Initialized data segment: store e global, static and constant data • Uninitialized data segment  Stack segment: • where parameters and local variables are allocated  Heap segment: • where dynamically allocated variables are allocated Text segment (Code segment) Stack segment Heap Segment Data segment MIPS
  • 6.
    Stack 6  Where parametersand local variables are allocated  Limited size  Stack overflow  Memory use in stack is temporary and auto release  Fast processing/low size Parameters Return Address where to begin execution when function exits Dynamic link pointer to caller's stack frame Static link pointer to lexical parent (for nested functions) Return value Local variables “Concept” Stack frame Text segment (Code segment) Stack frame Heap Segment Data segment Stack frame
  • 7.
    Heap 7  Large poolof memory  Dynamic allocation  Stays allocated until specifically deallocated  leak !  Must be accessed through a pointer  Large arrays, structures, or classes should be stored Heap  why?  Large & dynamic Parameters Return Address where to begin execution when function exits Dynamic link pointer to caller's stack frame Static link pointer to lexical parent (for nested functions) Return value Local variables “Concept” Stack frame Text segment (Code segment) Stack frame Heap Segment Data segment Stack frame
  • 8.
    Heap vs Stack 8 int _array[10];  stored in stack Stack _array int *_array = new int[n] • Pointer _array is stored in Stack • Data of array is stored in Heap _array 0x00FF Stack 10 Heap 0x00FF 0x000 5 Value of: ● _array : address where int “point” into in heap (0x00FF) ● (*_array): value at it's address on heap (10) ● (&_array): address of the memory which used for stored pointer _array in stack (0x0005) Always stored in stack ? Any chance to store _array in heap?
  • 9.
    FAQ 9  Why weuse Classname *Obj = new Classname();  instead of Classname Obj;
  • 10.
  • 11.
    What does memoryleaking mean? 11  Definition:  Particular type of unused memory, unable to release  Common:  Refer to any unwanted increase in memory usage  Different from memory fragmentation * for heap memory void Leak() { int *A = new int[1000]; // some code here // ... // without delete A // return; } 4000 bytes Return without free A → Leak
  • 12.
    What does itsconsequences ? 12  Application gets slow fps  Application is crashed  Device has been freeze, restarted
  • 13.
    Why does “memoryleak” happen? First, Let's see some examples 13
  • 14.
    Example 0 14  Forgetto release resources  No GC mechanic supported Button is pressed Save current floor On target floor ? Wait until lift is idle Go to required floor Release memory used to save current floor True Finished Memory Leaking here
  • 15.
    void Fa() { } void Fb() {} voidLeak() { int *a = new int[10]; Fa(); Fb(); return; } void main() { Leak(); } C/C++ Example 1 15  Leak memory caused by lacking of release dynamic memory … delete a[]; return; Solution Leak !
  • 16.
    C/C++ Example 2 16 Allocation a series, delete only one unit Leak ! for (int i = 0; i < 10; i++) { delete list[i]; } delete list; Solution void leak() { int **list = new int*[10]; for (int i = 0; i < 10; i++) { list[i] = new int; } delete list; return; }
  • 17.
    C/C++ Example 3 17 Leakmemory when using pointer-return- type delete []str; Avoid to call directly GenString() Solution char* GenString() { char *a = new char[10]; a[9] = '0'; return a; } void Leak() { char *str = GenString(); printf("%sn", str); printf("%sn", GenString()); }
  • 18.
    #include <cstdio> void Foo() { int*a = new int[100]; a = new int[1000]; } void Foo1() { int* a = new int[100]; int* b = new int[1000]; a = b; } C/C++ Example 4 18 Leak memory because of misunderstanding “=” operator in C++ Stack Heap A LEAK! Leak!
  • 19.
    C/C++ Example 5 19 voidmain() { Classname *A = new A(); ... ... //free A A = NULL; } Misunderstand how to free memory method in C/C++ Stack Heap A NULL LEAK!  Keep in mind we are using C/C++  Use MACRO for safe deallocating #define SAFE_DEL(a) {if(a){delele a;a = 0;}} Solution
  • 20.
    C/C++ Example 6- STL 20 class Element { int ID; public: Element(int id) { printf("Created %d at 0x%xn", id, this); ID = id; } ~Element() { printf("Destroy %d at 0x%xn", ID, this); } }; int main() { list<Element*> m_List; Element *e0 = new Element(0); Element *e1 = new Element(1); //add to list m_List.push_back(e0); m_List.push_back(e1); //clear list printf("-----Before clear-----n"); m_List.clear(); printf("-----After clear-----n"); return 0; } Created 0 addr 0xa719c0 Created 1 addr 0xa81a18 -----Before clear----- -----After clear----- Command prompt Memory leak here list Item 0 Item 1 e0 e1
  • 21.
    C/C++ Example 6– STL (cont.) 21 int main() { list<Element*> m_List; Element *e0 = new Element(0); Element *e1 = new Element(1); //add to list m_List.push_back(e0); m_List.push_back(e1); //clear list printf("-----Before clear-----n"); list <Element*>::iterator i; for (i = m_List.begin(); i != m_List.end(); i++) { delete *i; } m_List.clear(); printf("-----After clear-----n"); return 0; } Free data of each element pointer Created 0 addr 0xb61a28 Created 1 addr 0xb71a70 -----Before clear----- Destroy 0 addr 0xb61a28 Destroy 1 addr 0xb71a70 -----After clear----- Command prompt
  • 22.
    Example 7 22 class CB{ public: CB(){ m_iVal = 0; } ~CB(){} int m_iVal; }; class CA { public: CA(){ m_pB = 0; } ~CA(){ delete m_pB; m_pB = 0; } CB *m_pB; }; int main() { CB *B = new CB; CA *A = new CA(); A->m_pB = B; delete(A); printf("%d", B->m_iVal); } B A m_pB Access violation reading location …. Try to remove delete m_pB
  • 23.
    Example 7 (cont.) 23 classCB { public: CB(){ m_iVal = 0; } ~CB(){} int m_iVal; }; class CA { public: CA(){ m_pB = 0; } ~CA(){ delete m_pB; m_pB = 0; } CB *m_pB; }; int main() { CA *A = new CA(); A->m_pB = new CB() delete(A); } A m_pB Leak Delete or not? Use manual dealocate m_pB Solution
  • 24.
    24 C/C++ Example 8 classcA() { public : cA() {m_pdata = new int[100];} virtual ~cA() {delete[] m_pdata;} int *m_pdata; }; class cB: public cA() { public cB():cA() {m_pdata2 = new int[100];} ~cB() {delete []m_pdata2;} int *m_pdata2; } void main() { cA *A = new cB(); delete A; } Memory leak caused by misunderstanding finalization method Without “virtual”, in this case, m_pdata is not deleted → leak ALWAYS use virtual for finalization methods Solution
  • 25.
    C/C++ Example 9 25 Usingnew vs free. Destructor will be NOT invoked after free class MyClass { public MyClass() { m_pdata2 = new int[100]; } ~ MyClass() { delete []m_pdata2; } int *m_pdata2; } void main() { MyClass* p = new MyClass(); free(p); } Leak here
  • 26.
    What are reasonsof memory leak? 26  Forget/ misunderstand C/C++ mechanism  Out-of-Control (logic)
  • 27.
    Current Solutions 27  For“Forget/ misunderstand C/C++ mechanism”  Semi-automatic memory management  Reference Counting  Automatic memory management  Tracing Garbage Collection (GC): Java , C #  No GC mechanic for C/C++
  • 28.
    Reference Counter: Goodor bad ? 28  Reference counter: Simple method for memory conflict resolution  Algorithms: • Increase counter when use as reference • Decrease when release • Delete memory of counter is zero class IShareMem { public: IShareMem():m_iRefCounter(1){} virtual ~IShareMem(){} static IShareMem* SetReference(IShareMem* src) { src->m_iRefCounter++; return src; } void Release() { m_iRefCounter--; if (m_iRefCounter <= 0) { delete this; } } private: int m_iRefCounter; };
  • 29.
    Reference Counter: Goodor bad ? 29  Good:  Avoid conflict in memory usage. (See example no.7)  Bad:  Cause memory leak if user forget “release”  Hard to detect memory leak.  Sometimes CAN NOT DETECT LEAK by tool (leak but not really leak)
  • 30.
    Current Solutions -Disadvantage 30  Garbage collectors generally can do nothing about logical memory leaks 0 1 2 n .. . Alloc Alloc Alloc Alloc Which is really needed?A B D E Z Do I alloc some- where without release? Somethings else is pointed to an object
  • 31.
    C/C++ How to avoid,detect? 31  Rule:  Remember to release dynamic data (pointer)  HARD  Keep our resource in well controlled  TOO HARD  Detect  By phenomenon on device ?  not exactly  By review source ?  TOO HARD  By tool  VC++ memory leak debugging  External tool  Cannot detect some cases.
  • 32.
    C/C++ How to solve? 32 Easy to detect, but hard to solve  Experience  Organize source and keep it in control  Such as a document about resource ?!? Applicatio n Leak log data Detect Memory leak Leak InformationAnalysis Experience Knowledge Fix and test
  • 33.
  • 34.
    Memory leak –quick detection 34  Windows: use task manager / process tab  Android: adb shell top -m <number_of_record> See VSS, RSS
  • 35.
    Use Visual studiosupported function 35  Use __CrtDumpMemoryLeaks  Advantage  Easy to use  Fully report about leak when application completed  Free  Disadvantage  Cannot detect run-time  Fail if application Crashed  Presentation:  Manually coding by user  Use some lib such as VLD
  • 36.
    Debug in Visualstudio 36
  • 37.
    VLD Tool 37  http://www.codeproject.com/KB/applications/visualleakdetector.aspx http://vld.codeplex.com/  Include vld.h in source  Add vld.lib #include "vld.h" #pragma comment(lib, "vld.lib")
  • 38.
    VLD Tool 38  Afterfinish application normally, memory leak information will be displayed in output WARNING: Visual Leak Detector detected memory leaks! ---------- Block 3 at 0x006F4F98: 12 bytes ---------- Call Stack: c:usersricky.ngkdesktoptestleaktestleakmain.cpp (81): TestLeak.exe!Init + 0x7 bytes c:usersricky.ngkdesktoptestleaktestleakmain.cpp (108): TestLeak.exe!main f:ddvctoolscrt_bldself_x86crtsrccrtexe.c (586): TestLeak.exe!__tmainCRTStartup + 0x19 bytes f:ddvctoolscrt_bldself_x86crtsrccrtexe.c (403): TestLeak.exe!mainCRTStartup 0x76BBED6C (File and line number not available): kernel32.dll!BaseThreadInitThunk + 0x12 bytes 0x772237F5 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0xEF bytes 0x772237C8 (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0xC2 bytes Data: 74 A7 DF 00 01 00 00 00 20 60 6F 00 t....... .`o..... Double click the stack to navigate to source
  • 39.
    VLD Tool  Likeany leak detect tools, shows where memory was allocated without free  User have to analyst to find real reason
  • 40.
    Debug memory leakrun-time 40  Use some tool, such as:  Glow code: http://www.glowcode.com/  Memory validator: http://www.softwareverify.com/cpp- memory.php  Advantage  Runtime checking  Nice Interface  Disadvantage  Not free  Not easy to use. Need tutorial  Note: Those tool cannot working well with VLD
  • 41.
    The end! Thanks foryour attention
  • 42.
    Appendix – Topten excuses for memory leak  A little memory leak is no big thing  Nobody will ever find out  Complex programs always have memory leak  My application Framework is too entangled  The memory leak is in the operation system  The memory leak is in my third party tools  Product development cycles are too fast  It’s hard to get good programmer today  Leaks and bugs are the price you pay for GUI  Everything else leaks, why shouldn’t mine? http://www.troubleshooters.com/codecorn/memoryleak.htm