追踪内存分配 重载全局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 #include "../src/include/local.h" #define ps(str) std::cout << str << std::endl struct AllocationMetrics { uint32_t TotalAllocated = 0 ; uint32_t TotalFreed = 0 ; uint32_t CurrentUsage () { return TotalAllocated - TotalFreed; } }; AllocationMetrics s_AllocationMetrics;struct Object { int x, y, z; };void * operator new (size_t size) { s_AllocationMetrics.TotalAllocated += size; std ::cout << "Allocating " << size << " bytes\n" ; return malloc (size); }void operator delete (void * memory,size_t size) { s_AllocationMetrics.TotalFreed += size; free (memory); }void PrintMemoryUsage () { std ::cout << "Memory Usage: " << s_AllocationMetrics.CurrentUsage() << " bytes\n" ; }int main () { PrintMemoryUsage(); std ::string name = "Cherno" ; PrintMemoryUsage(); { std ::unique_ptr <Object> obj = std ::make_unique<Object>(); PrintMemoryUsage(); } PrintMemoryUsage(); std ::cin .get(); }
简单区分左右值 注意:std::string& name
此参数仅能接收左值,但是加上const
,即const std::string &name
此参数既能接收左值又能接收右值,编译器构造一个临时变量(左值),作为参数传递给函数
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 #include "../src/include/local.h" #define ps(str) std::cout << str << std::endl void PrintName (std ::string && name) { std ::cout << "[Rvalue] " << name << std ::endl ; }void PrintName (const std ::string & name) { std ::cout << "[Lvalue] " << name << std ::endl ; }int main () { int i = 10 ; std ::string firstName = "yan" ; std ::string lastName = "Chernikov" ; std ::string fullName = firstName + lastName; PrintName(fullName); PrintName(firstName + lastName); std ::cin .get(); }
使用静态代码分析工具PVS-Studio 安装后,在Vs菜单栏->扩展->PVS->check-current-file,
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 #include <iostream> struct Entity { };Entity* LoadEntity () { return nullptr ; }int main () { Entity* entity = LoadEntity(); if (entity) { } const char * string = "Hello" ; char * buffer = new char [strlen (string )]; memcpy (buffer,string ,strlen (string )); uint32_t width = 800 , height = 600 ; uint32_t * buffer = new uint32_t [width*height]; for (uint32_t y = 0 ; y < height; y++) { for (uint32_t x = 0 ; x < width; y++) { buffer[x + y * width] = 0 ; } } std ::cin .get(); }
上面代码明显错误/优化点:
entity永远为nullptr
,分支只能降低程序执行速度
buffer大小分配有问题
第2层for循环有问题
Argument Evaluation Order(参数求值顺序)
PVS报错:unspecified behavior,The order of argument evaluation is not defined for 'PrintSum' function,Consider inspecting the 'value' variable
c++标准没有指定函数定义的参数的求值顺序
1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream> void PrintSum (int a, int b) { std ::cout << a << " + " << b << " = " << (a + b) << std ::endl ; }int main () { int value = 0 ; PrintSum(value++,value++); std ::cin .get(); }
MSVC 开启c++17选项
Debug模式
Release模式
的结果都是1+0=1
,并且编译没有warning
clang 10.0.0 clang++ prog.cc -Wall -Wextra -std=c++17
1 2 3 4 prog.cc:10:16: warning: multiple unsequenced modifications to 'value' [-Wunsequenced] PrintSum(value++,value++); ^ ~~ 1 warning generated.
执行结果:0+1=1
,貌似是从左到右执行
gcc 9.3.0 g++ prog.cc -Wall -Wextra -I/opt/wandbox/boost-1.73.0/gcc-9.3.0/include -std=c++17
1 2 3 4 5 prog.cc: In function 'int main()': prog.cc:10:24: warning: operation on 'value' may be undefined [-Wsequence-point] 10 | PrintSum(value++,value++); | ~~~~~^~prog.cc:10:24: warning: operation on 'value' may be undefined [-Wsequence-point]
执行结果:1+0=1
,和MSVC的结果一样