C++学习笔记-Track Memory Allocations

内存分配跟踪是C++程序调试和性能优化的重要技术。通过重载new和delete操作符,我们可以监控程序的内存使用情况,检测内存泄漏,分析内存分配模式。

基本内存分配跟踪

 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
#include <iostream>
#include <memory>

struct AllocationMetrics
{
    uint32_t TotalAllocated = 0;
    uint32_t TotalFreed = 0;

    uint32_t CurrentUsage() { return TotalAllocated - TotalFreed; }
};

static AllocationMetrics s_AllocationMetrics;

/* 重载new和delete操作符来跟踪内存分配 */
void* operator new(size_t size)
{
    s_AllocationMetrics.TotalAllocated += size;
    return malloc(size);
}

void operator delete(void* memory, size_t size)
{
    s_AllocationMetrics.TotalFreed += size;
    free(memory);
}

static void PrintMemoryUsage()
{
    std::cout << "Memory Usage: " << s_AllocationMetrics.CurrentUsage() << " bytes" << std::endl;
}

struct Object
{
    int x, y, z;
};

void BasicTrackingDemo()
{
    std::cout << "=== Basic Memory Tracking Demo ===" << std::endl;
    
    PrintMemoryUsage();
    {
        std::unique_ptr<Object> obj = std::make_unique<Object>();
        PrintMemoryUsage();
    }
    PrintMemoryUsage();
}

int main()
{
    BasicTrackingDemo();
    return 0;
}

详细的内存分配跟踪器

  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
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#include <iostream>
#include <memory>
#include <vector>
#include <map>
#include <string>
#include <iomanip>
#include <mutex>

class MemoryTracker
{
private:
    struct AllocationInfo
    {
        size_t size;
        std::string file;
        int line;
        std::string function;
        
        AllocationInfo() = default;
        AllocationInfo(size_t s, const std::string& f, int l, const std::string& func)
            : size(s), file(f), line(l), function(func) {}
    };
    
    static std::map<void*, AllocationInfo> s_Allocations;
    static size_t s_TotalAllocated;
    static size_t s_TotalFreed;
    static size_t s_AllocationCount;
    static size_t s_FreeCount;
    static std::mutex s_Mutex;
    
public:
    static void* Allocate(size_t size, const char* file = nullptr, int line = 0, const char* function = nullptr)
    {
        std::lock_guard<std::mutex> lock(s_Mutex);
        
        void* ptr = malloc(size);
        if (ptr)
        {
            s_TotalAllocated += size;
            s_AllocationCount++;
            
            if (file && function)
            {
                s_Allocations[ptr] = AllocationInfo(size, file, line, function);
            }
            else
            {
                s_Allocations[ptr] = AllocationInfo(size, "unknown", 0, "unknown");
            }
            
            std::cout << "[ALLOC] " << size << " bytes at " << ptr;
            if (file && function)
            {
                std::cout << " (" << file << ":" << line << " in " << function << ")";
            }
            std::cout << std::endl;
        }
        
        return ptr;
    }
    
    static void Deallocate(void* ptr, size_t size = 0)
    {
        if (!ptr) return;
        
        std::lock_guard<std::mutex> lock(s_Mutex);
        
        auto it = s_Allocations.find(ptr);
        if (it != s_Allocations.end())
        {
            size_t allocatedSize = it->second.size;
            s_TotalFreed += allocatedSize;
            s_FreeCount++;
            
            std::cout << "[FREE ] " << allocatedSize << " bytes at " << ptr 
                      << " (" << it->second.file << ":" << it->second.line 
                      << " in " << it->second.function << ")" << std::endl;
            
            s_Allocations.erase(it);
        }
        else
        {
            std::cout << "[FREE ] Unknown allocation at " << ptr << std::endl;
        }
        
        free(ptr);
    }
    
    static void PrintStatistics()
    {
        std::lock_guard<std::mutex> lock(s_Mutex);
        
        std::cout << "\n=== Memory Statistics ===" << std::endl;
        std::cout << "Total allocated: " << s_TotalAllocated << " bytes" << std::endl;
        std::cout << "Total freed: " << s_TotalFreed << " bytes" << std::endl;
        std::cout << "Current usage: " << (s_TotalAllocated - s_TotalFreed) << " bytes" << std::endl;
        std::cout << "Allocation count: " << s_AllocationCount << std::endl;
        std::cout << "Free count: " << s_FreeCount << std::endl;
        std::cout << "Outstanding allocations: " << s_Allocations.size() << std::endl;
    }
    
    static void PrintLeaks()
    {
        std::lock_guard<std::mutex> lock(s_Mutex);
        
        if (s_Allocations.empty())
        {
            std::cout << "\n=== No Memory Leaks Detected ===" << std::endl;
            return;
        }
        
        std::cout << "\n=== Memory Leaks Detected ===" << std::endl;
        std::cout << "Outstanding allocations:" << std::endl;
        
        for (const auto& [ptr, info] : s_Allocations)
        {
            std::cout << "  " << info.size << " bytes at " << ptr 
                      << " (" << info.file << ":" << info.line 
                      << " in " << info.function << ")" << std::endl;
        }
    }
    
    static void Reset()
    {
        std::lock_guard<std::mutex> lock(s_Mutex);
        
        s_Allocations.clear();
        s_TotalAllocated = 0;
        s_TotalFreed = 0;
        s_AllocationCount = 0;
        s_FreeCount = 0;
    }
};

// 静态成员定义
std::map<void*, MemoryTracker::AllocationInfo> MemoryTracker::s_Allocations;
size_t MemoryTracker::s_TotalAllocated = 0;
size_t MemoryTracker::s_TotalFreed = 0;
size_t MemoryTracker::s_AllocationCount = 0;
size_t MemoryTracker::s_FreeCount = 0;
std::mutex MemoryTracker::s_Mutex;

// 宏定义用于自动捕获文件名、行号和函数名
#define TRACKED_NEW(size) MemoryTracker::Allocate(size, __FILE__, __LINE__, __FUNCTION__)
#define TRACKED_DELETE(ptr) MemoryTracker::Deallocate(ptr)

// 重载全局new和delete(可选)
void* operator new(size_t size)
{
    return MemoryTracker::Allocate(size);
}

void operator delete(void* ptr) noexcept
{
    MemoryTracker::Deallocate(ptr);
}

void operator delete(void* ptr, size_t size) noexcept
{
    MemoryTracker::Deallocate(ptr, size);
}

void DetailedTrackingDemo()
{
    std::cout << "=== Detailed Memory Tracking Demo ===" << std::endl;
    
    MemoryTracker::Reset();
    
    // 正常分配和释放
    {
        int* arr = static_cast<int*>(TRACKED_NEW(sizeof(int) * 10));
        TRACKED_DELETE(arr);
    }
    
    // 使用智能指针
    {
        auto ptr = std::make_unique<int>(42);
        // 自动释放
    }
    
    // 故意制造内存泄漏
    {
        int* leak = static_cast<int*>(TRACKED_NEW(sizeof(int) * 5));
        // 故意不释放
    }
    
    MemoryTracker::PrintStatistics();
    MemoryTracker::PrintLeaks();
}

int main()
{
    DetailedTrackingDemo();
    return 0;
}

内存分配分析器

  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
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#include <iostream>
#include <memory>
#include <vector>
#include <map>
#include <chrono>
#include <algorithm>
#include <iomanip>

class MemoryProfiler
{
private:
    struct AllocationRecord
    {
        size_t size;
        std::chrono::high_resolution_clock::time_point timestamp;
        std::string location;
        bool isActive;
        
        AllocationRecord(size_t s, const std::string& loc)
            : size(s), timestamp(std::chrono::high_resolution_clock::now()), 
              location(loc), isActive(true) {}
    };
    
    static std::map<void*, AllocationRecord> s_Records;
    static std::vector<AllocationRecord> s_History;
    static size_t s_PeakUsage;
    static size_t s_CurrentUsage;
    static std::chrono::high_resolution_clock::time_point s_StartTime;
    
public:
    static void Initialize()
    {
        s_StartTime = std::chrono::high_resolution_clock::now();
        s_PeakUsage = 0;
        s_CurrentUsage = 0;
        s_Records.clear();
        s_History.clear();
    }
    
    static void* Allocate(size_t size, const std::string& location = "unknown")
    {
        void* ptr = malloc(size);
        if (ptr)
        {
            s_Records[ptr] = AllocationRecord(size, location);
            s_History.push_back(AllocationRecord(size, location));
            
            s_CurrentUsage += size;
            if (s_CurrentUsage > s_PeakUsage)
            {
                s_PeakUsage = s_CurrentUsage;
            }
        }
        return ptr;
    }
    
    static void Deallocate(void* ptr)
    {
        if (!ptr) return;
        
        auto it = s_Records.find(ptr);
        if (it != s_Records.end())
        {
            s_CurrentUsage -= it->second.size;
            
            // 标记为已释放
            for (auto& record : s_History)
            {
                if (record.location == it->second.location && 
                    record.size == it->second.size && record.isActive)
                {
                    record.isActive = false;
                    break;
                }
            }
            
            s_Records.erase(it);
        }
        
        free(ptr);
    }
    
    static void PrintReport()
    {
        auto now = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - s_StartTime);
        
        std::cout << "\n=== Memory Profiling Report ===" << std::endl;
        std::cout << "Profiling duration: " << duration.count() << " ms" << std::endl;
        std::cout << "Current usage: " << s_CurrentUsage << " bytes" << std::endl;
        std::cout << "Peak usage: " << s_PeakUsage << " bytes" << std::endl;
        std::cout << "Total allocations: " << s_History.size() << std::endl;
        std::cout << "Active allocations: " << s_Records.size() << std::endl;
        
        // 按位置分组统计
        std::map<std::string, size_t> locationStats;
        std::map<std::string, size_t> locationCounts;
        
        for (const auto& record : s_History)
        {
            locationStats[record.location] += record.size;
            locationCounts[record.location]++;
        }
        
        std::cout << "\nAllocation by location:" << std::endl;
        for (const auto& [location, totalSize] : locationStats)
        {
            std::cout << "  " << std::setw(20) << location 
                      << ": " << std::setw(8) << totalSize << " bytes"
                      << " (" << locationCounts[location] << " allocations)" << std::endl;
        }
        
        // 分析分配大小分布
        std::map<size_t, size_t> sizeDistribution;
        for (const auto& record : s_History)
        {
            // 按2的幂次分组
            size_t bucket = 1;
            while (bucket < record.size)
            {
                bucket *= 2;
            }
            sizeDistribution[bucket]++;
        }
        
        std::cout << "\nAllocation size distribution:" << std::endl;
        for (const auto& [size, count] : sizeDistribution)
        {
            std::cout << "  " << std::setw(8) << (size/2 + 1) << "-" << std::setw(8) << size 
                      << " bytes: " << count << " allocations" << std::endl;
        }
    }
    
    static void PrintTimeline()
    {
        std::cout << "\n=== Allocation Timeline ===" << std::endl;
        
        size_t runningTotal = 0;
        for (const auto& record : s_History)
        {
            auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
                record.timestamp - s_StartTime);
            
            if (record.isActive)
            {
                runningTotal += record.size;
                std::cout << "[+" << std::setw(4) << elapsed.count() << "ms] "
                          << "+" << record.size << " bytes (" << record.location 
                          << ") Total: " << runningTotal << std::endl;
            }
            else
            {
                runningTotal -= record.size;
                std::cout << "[+" << std::setw(4) << elapsed.count() << "ms] "
                          << "-" << record.size << " bytes (" << record.location 
                          << ") Total: " << runningTotal << std::endl;
            }
        }
    }
};

// 静态成员定义
std::map<void*, MemoryProfiler::AllocationRecord> MemoryProfiler::s_Records;
std::vector<MemoryProfiler::AllocationRecord> MemoryProfiler::s_History;
size_t MemoryProfiler::s_PeakUsage = 0;
size_t MemoryProfiler::s_CurrentUsage = 0;
std::chrono::high_resolution_clock::time_point MemoryProfiler::s_StartTime;

// 便利宏
#define PROFILE_ALLOC(size, name) MemoryProfiler::Allocate(size, name)
#define PROFILE_FREE(ptr) MemoryProfiler::Deallocate(ptr)

void ProfilingDemo()
{
    std::cout << "=== Memory Profiling Demo ===" << std::endl;
    
    MemoryProfiler::Initialize();
    
    // 模拟不同的分配模式
    std::vector<void*> allocations;
    
    // 小对象分配
    for (int i = 0; i < 10; ++i)
    {
        void* ptr = PROFILE_ALLOC(32, "small_objects");
        allocations.push_back(ptr);
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
    
    // 中等对象分配
    for (int i = 0; i < 5; ++i)
    {
        void* ptr = PROFILE_ALLOC(1024, "medium_objects");
        allocations.push_back(ptr);
        std::this_thread::sleep_for(std::chrono::milliseconds(20));
    }
    
    // 大对象分配
    void* largePtr = PROFILE_ALLOC(10240, "large_object");
    allocations.push_back(largePtr);
    
    // 释放一些对象
    for (size_t i = 0; i < allocations.size() / 2; ++i)
    {
        PROFILE_FREE(allocations[i]);
        std::this_thread::sleep_for(std::chrono::milliseconds(5));
    }
    
    MemoryProfiler::PrintReport();
    MemoryProfiler::PrintTimeline();
    
    // 清理剩余分配
    for (size_t i = allocations.size() / 2; i < allocations.size(); ++i)
    {
        PROFILE_FREE(allocations[i]);
    }
}

int main()
{
    ProfilingDemo();
    return 0;
}

实际应用场景

  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
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
#include <iostream>
#include <memory>
#include <vector>
#include <string>
#include <fstream>

// 内存池分配器
class MemoryPool
{
private:
    struct Block
    {
        void* data;
        size_t size;
        bool inUse;
        
        Block(size_t s) : size(s), inUse(false)
        {
            data = malloc(s);
        }
        
        ~Block()
        {
            free(data);
        }
    };
    
    std::vector<std::unique_ptr<Block>> blocks;
    size_t totalAllocated = 0;
    size_t totalUsed = 0;
    
public:
    void* Allocate(size_t size)
    {
        // 查找合适的空闲块
        for (auto& block : blocks)
        {
            if (!block->inUse && block->size >= size)
            {
                block->inUse = true;
                totalUsed += block->size;
                std::cout << "[POOL] Reused block of " << block->size << " bytes" << std::endl;
                return block->data;
            }
        }
        
        // 创建新块
        auto newBlock = std::make_unique<Block>(size);
        void* ptr = newBlock->data;
        newBlock->inUse = true;
        
        totalAllocated += size;
        totalUsed += size;
        
        std::cout << "[POOL] Created new block of " << size << " bytes" << std::endl;
        blocks.push_back(std::move(newBlock));
        
        return ptr;
    }
    
    void Deallocate(void* ptr)
    {
        for (auto& block : blocks)
        {
            if (block->data == ptr && block->inUse)
            {
                block->inUse = false;
                totalUsed -= block->size;
                std::cout << "[POOL] Freed block of " << block->size << " bytes" << std::endl;
                return;
            }
        }
        std::cout << "[POOL] Warning: Attempted to free unknown pointer" << std::endl;
    }
    
    void PrintStats()
    {
        std::cout << "\n=== Memory Pool Statistics ===" << std::endl;
        std::cout << "Total blocks: " << blocks.size() << std::endl;
        std::cout << "Total allocated: " << totalAllocated << " bytes" << std::endl;
        std::cout << "Currently used: " << totalUsed << " bytes" << std::endl;
        std::cout << "Pool efficiency: " << (totalUsed * 100.0 / totalAllocated) << "%" << std::endl;
        
        size_t inUseCount = 0;
        for (const auto& block : blocks)
        {
            if (block->inUse) inUseCount++;
        }
        std::cout << "Blocks in use: " << inUseCount << "/" << blocks.size() << std::endl;
    }
};

// 内存使用监控器
class MemoryMonitor
{
private:
    static size_t s_CurrentUsage;
    static size_t s_PeakUsage;
    static size_t s_AllocationCount;
    
public:
    static void RecordAllocation(size_t size)
    {
        s_CurrentUsage += size;
        s_AllocationCount++;
        
        if (s_CurrentUsage > s_PeakUsage)
        {
            s_PeakUsage = s_CurrentUsage;
        }
        
        // 检查是否超过阈值
        const size_t WARNING_THRESHOLD = 1024 * 1024; // 1MB
        if (s_CurrentUsage > WARNING_THRESHOLD)
        {
            std::cout << "[WARNING] Memory usage exceeded " << WARNING_THRESHOLD 
                      << " bytes (current: " << s_CurrentUsage << ")" << std::endl;
        }
    }
    
    static void RecordDeallocation(size_t size)
    {
        if (s_CurrentUsage >= size)
        {
            s_CurrentUsage -= size;
        }
    }
    
    static void PrintStatus()
    {
        std::cout << "\n=== Memory Monitor Status ===" << std::endl;
        std::cout << "Current usage: " << s_CurrentUsage << " bytes" << std::endl;
        std::cout << "Peak usage: " << s_PeakUsage << " bytes" << std::endl;
        std::cout << "Total allocations: " << s_AllocationCount << std::endl;
    }
    
    static void SaveReport(const std::string& filename)
    {
        std::ofstream file(filename);
        if (file.is_open())
        {
            file << "Memory Usage Report\n";
            file << "==================\n";
            file << "Current usage: " << s_CurrentUsage << " bytes\n";
            file << "Peak usage: " << s_PeakUsage << " bytes\n";
            file << "Total allocations: " << s_AllocationCount << "\n";
            file.close();
            std::cout << "Memory report saved to " << filename << std::endl;
        }
    }
};

size_t MemoryMonitor::s_CurrentUsage = 0;
size_t MemoryMonitor::s_PeakUsage = 0;
size_t MemoryMonitor::s_AllocationCount = 0;

// 智能指针包装器,自动跟踪内存
template<typename T>
class TrackedPtr
{
private:
    T* ptr;
    size_t size;
    
public:
    TrackedPtr(size_t count = 1) : size(sizeof(T) * count)
    {
        ptr = static_cast<T*>(malloc(size));
        MemoryMonitor::RecordAllocation(size);
        std::cout << "[TRACKED] Allocated " << size << " bytes for " << typeid(T).name() << std::endl;
    }
    
    ~TrackedPtr()
    {
        if (ptr)
        {
            MemoryMonitor::RecordDeallocation(size);
            std::cout << "[TRACKED] Deallocated " << size << " bytes for " << typeid(T).name() << std::endl;
            free(ptr);
        }
    }
    
    // 移动构造函数
    TrackedPtr(TrackedPtr&& other) noexcept : ptr(other.ptr), size(other.size)
    {
        other.ptr = nullptr;
        other.size = 0;
    }
    
    // 禁止拷贝
    TrackedPtr(const TrackedPtr&) = delete;
    TrackedPtr& operator=(const TrackedPtr&) = delete;
    
    T* get() { return ptr; }
    T& operator*() { return *ptr; }
    T* operator->() { return ptr; }
    T& operator[](size_t index) { return ptr[index]; }
};

void PracticalApplicationsDemo()
{
    std::cout << "=== Practical Applications Demo ===" << std::endl;
    
    // 1. 内存池使用
    std::cout << "\n1. Memory Pool Usage:" << std::endl;
    MemoryPool pool;
    
    std::vector<void*> poolAllocations;
    
    // 分配一些内存
    for (int i = 0; i < 5; ++i)
    {
        void* ptr = pool.Allocate(64);
        poolAllocations.push_back(ptr);
    }
    
    pool.PrintStats();
    
    // 释放一些内存
    for (size_t i = 0; i < 3; ++i)
    {
        pool.Deallocate(poolAllocations[i]);
    }
    
    // 重新分配(应该重用已释放的块)
    void* reusedPtr = pool.Allocate(64);
    
    pool.PrintStats();
    
    // 2. 内存监控
    std::cout << "\n2. Memory Monitoring:" << std::endl;
    
    {
        TrackedPtr<int> intArray(100);
        TrackedPtr<double> doubleArray(50);
        
        MemoryMonitor::PrintStatus();
        
        // 模拟大量分配
        std::vector<TrackedPtr<char>> charArrays;
        for (int i = 0; i < 10; ++i)
        {
            charArrays.emplace_back(1024); // 1KB each
        }
        
        MemoryMonitor::PrintStatus();
    } // 自动释放
    
    MemoryMonitor::PrintStatus();
    MemoryMonitor::SaveReport("memory_report.txt");
    
    // 3. 内存泄漏检测示例
    std::cout << "\n3. Memory Leak Detection:" << std::endl;
    
    // 故意创建泄漏
    TrackedPtr<int>* leak = new TrackedPtr<int>(10);
    // 故意不删除,模拟泄漏
    
    MemoryMonitor::PrintStatus();
    
    std::cout << "\nNote: TrackedPtr at " << leak << " was not properly deleted (simulated leak)" << std::endl;
    
    // 清理(在实际应用中应该自动检测)
    delete leak;
}

int main()
{
    PracticalApplicationsDemo();
    return 0;
}

总结

  1. 内存跟踪基础:通过重载new/delete操作符监控内存分配
  2. 跟踪技术
    • 全局操作符重载
    • 分配记录存储
    • 统计信息收集
    • 泄漏检测
  3. 高级功能
    • 调用栈跟踪
    • 分配时间线
    • 内存使用模式分析
    • 峰值使用监控
  4. 实际应用
    • 内存泄漏检测
    • 性能分析
    • 内存池管理
    • 资源使用监控
  5. 工具和技术
    • 自定义分配器
    • 智能指针包装
    • 内存池优化
    • 实时监控
  6. 最佳实践
    • 在调试版本中启用跟踪
    • 使用RAII管理资源
    • 定期检查内存使用
    • 自动化泄漏检测
    • 性能影响最小化
updatedupdated2025-09-202025-09-20