C语言中如何实现跟踪内存分配的机制?

摘要:内存是非常重要的东西 知道你的程序什么时候分配内存 特别是堆内存 是很有用的 如果知道程序在哪里分配内存 就有可能减少它 从而优化程序 也可以更好地了解程序是如何工作的 需要重写new运算符 来检测发生的内存分配 我们可以通过在operat
内存是非常重要的东西 知道你的程序什么时候分配内存 特别是堆内存 是很有用的 如果知道程序在哪里分配内存 就有可能减少它 从而优化程序 也可以更好地了解程序是如何工作的 需要重写new运算符 来检测发生的内存分配 我们可以通过在operator new中加入一个断点 来追踪这些内存分配的来源 #include <iostream> void* operator new(size_t size) { std::cout << "Allocating " << size << " bytes\n"; return malloc(size); } struct Object { int x, y, z; }; int main() { Object* obj = new Object; std::string string = "Miku"; } 在return malloc(size);这一行(第7行)设置断点 查看调用堆栈 Project_test.exe!operator new(unsigned __int64 size) 行 7 Project_test.exe!main() 行 17 所以就是Object* obj = new Object; 这一行调用了new std::string string = "Miku"; 这就不会发生堆分配 因为这是小字符串 但是debug模式下仍然会发生分配 查看调用堆栈 Project_test.exe!operator new(unsigned __int64 size) 行 7 Project_test.exe!std::_Default_allocate_traits::_Allocate(const unsigned __int64 _Bytes) 行 87 对调用堆栈的第2行 右键 - 转到源代码 可以看到 // 来自于<xmemory> struct _Default_allocate_traits { __declspec(allocator) static #ifdef __clang__ // Clang and MSVC implement P0784R7 differently; see GH-1532 _CONSTEXPR20 #endif // defined(__clang__) void* _Allocate(const size_t _Bytes) { return ::operator new(_Bytes); } 是在这里调用了operator new 如果把调用堆栈的显示外部代码关掉 就会变成 Project_test.exe!operator new(unsigned __int64 size) 行 7 [外部代码] Project_test.exe!main() 行 17 [外部代码] 如果使用智能指针std::unique_ptr obj = std::make_unique(); 而不是显式地调用new Project_test.exe!operator new(unsigned __int64 size) 行 8 Project_test.exe!std::make_unique<Object,0>() 行 3465 对调用堆栈的第2行转到源代码 // 来自于<memory> _EXPORT_STD template <class _Ty, class... _Types, enable_if_t<!is_array_v<_Ty>, int> = 0> _NODISCARD_SMART_PTR_ALLOC _CONSTEXPR23 unique_ptr<_Ty> make_unique(_Types&&... _Args) { // make a unique_ptr return unique_ptr<_Ty>(new _Ty(_STD forward<_Types>(_Args)...)); } make_unique是调用了new #include <iostream> #include <memory> void operator delete(void* memory) { free(memory); } struct Object { int x, y, z; };
阅读全文