Load operator new and operator Delete from scratch to implement a simple memory leakage Tracker

Source: Internet
Author: User

First, let's talk about the implementation idea: we can implement a trace class. When operator new is called, we will add the pointer to the allocated memory, the current file, the current row, and other information to the trace member map container, delete this information when you call operator Delete. Defines a global trace object. When the program ends and the object is parsed, it determines whether the MAP member has information. If so, it is printed, indicating that memory leakage has occurred, the output shows which file is allocated with memory but not released.


Debugnew. h:

C ++ code
1
2
3
4
5
6
7
8
9
# Ifndef _ debug_new_h _
# DEFINE _ debug_new_h _

# Ifndef ndebug
# Include "tracer. H"
# Define new (_ file __, _ line __)
# Endif // ndebug

# Endif/_ debug_new_h _

Trace. h:

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# Ifndef _ tracer_h _
# DEFINE _ tracer_h _

# Include <map>

# Ifndef ndebug

Void * operator new (size_t size, const char * file, long line );
Void operator Delete (void * P );

Void * operator new [] (size_t size, const char * file, long line );
Void operator Delete [] (void * P );

Class Tracer
{
PRIVATE:
Class entry
{
Public:
Entry (const char * file = 0, long line = 0)
: File _ (file), line _ (line ){}
Const char * file () const
{
Return file _;
}
Long Line () const
{
Return line _;
}
PRIVATE:
Const char * file _;
Long Line _;
};
Public:
Tracer ();
~ Tracer ();
Static bool ready;

Void add (void * P, const char * file, long line );
Void remove (void * P );
Void dump ();

PRIVATE:
STD: Map <void *, entry> mapentry _;
};

# Endif // ndebug

# Endif // _ tracer_h _

Trace. cpp:


C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Include <iostream>
# Include "tracer. H"

# Ifndef ndebug

Bool tracer: Ready = false;

Tracer: tracer ()
{
Ready = true;
}

Tracer ::~ Tracer ()
{
Ready = false;
Dump ();
}

Void tracer: add (void * P, const char * file, long line)
{
Mapentry _ [p] = entry (file, line );
}

Void tracer: Remove (void * P)
{
STD: Map <void *, entry >:: iterator it;
It = mapentry _. Find (P );
If (it! = Mapentry _. End ())
{
Mapentry _. Erase (it );
}
}

Void tracer: dump ()
{
If (mapentry _. Size ()> 0)
{
STD: cout <"*** Memory Leak (s):" <STD: Endl;
STD: Map <void *, entry >:: iterator it;

For (IT = mapentry _. Begin (); it! = Mapentry _. End (); ++ it)
{
Const char * file = it-> second. File ();
Long line = it-> second. Line ();
Int ADDR = reinterpret_cast <int> (IT-> first );
STD: cout <"0x" <STD: Hex <ADDR <":"
<File <", line" <STD: Dec <line <STD: Endl;

}
STD: cout <STD: Endl;
}
}

Tracer newtrace;

Void * operator new (size_t size, const char * file, long line)
{
Void * P = malloc (size );
If (tracer: Ready)
{
Newtrace. Add (p, file, line );
}
Return P;
}

Void operator Delete (void * P)
{
If (tracer: Ready)
{
Newtrace. Remove (P );
}
Free (P );
}

Void * operator new [] (size_t size, const char * file, long line)
{
Void * P = malloc (size );
If (tracer: Ready)
{
Newtrace. Add (p, file, line );
}
Return P;
}

Void operator Delete [] (void * P)
{
If (tracer: Ready)
{
Newtrace. Remove (P );
}
Free (P );
}
# Endif // # ifndef ndebug

Main. cpp:

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Include <iostream>
Using namespace STD;

# Include "debugnew. H"

Int main (void)
{
Int * P = new int;
/* Delete P ;*/

Int * P2 = new int [5];
/* Delete [] P2 ;*/

Return 0;
}



Program # define new (_ file __,_ _ line __);
To use the _ file __, and _ line _ macros to represent the file name and number of rows respectively. Reload


Operator new and operator new [] functions and corresponding Delete functions. For more details, see here. When the Global Object newtrace
Call the dump member during structure analysis.


Function. If new and delete do not match, the map will leak information and print it out.


In addition, the memory leakage is tracked only in the debug version (ndebug is not defined), so the # ifndef ndebug
...
# Endif


Generally, the C ++ library does not contain # define new (_ file __, _ line __);
That is, the call is still the original new, but this type is not reloaded in the program.


Because the new and delete functions cannot track memory leaks such as map containers, normally using C ++ library containers will not cause memory leaks,


The C ++ library has been fully implemented, at least much better than the program we write.


Refer:

C ++ primer version 4
Valid tive C ++ 3rd
C ++ programming specifications

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.