C++内存分配的四个层面 :
四个层面的比较:
内存分配与释放的测试:
void* p1 = malloc(512); //512 bytes free(p1); complex<int>* p2 = new complex<int>; //one object delete p2; void* p3 = ::operator new(512); //512 bytes ::operator delete(p3); //以下使用 C++ 标准库提供的 allocators。 //其接口虽有标准规格,但实现商业并未完全遵守;下面三者形式略同。 #ifdef _MSC_VER //以下兩函數都是 non-static,定要通過 object 調用。以下分配 3 個 ints. int* p4 = allocator<int>().allocate(3, (int*)0); allocator<int>().deallocate(p4,3); #endif #ifdef __BORLANDC__ //以下兩函數都是 non-static,定要通過 object 調用。以下分配 5 個 ints. int* p4 = allocator<int>().allocate(5); allocator<int>().deallocate(p4,5); #endif #ifdef __GNUC__ //以下兩函數都是 static,可通過全名調用之。以下分配 512 bytes. //void* p4 = alloc::allocate(512); //alloc::deallocate(p4,512); //以下兩函數都是 non-static,定要通過 object 調用。以下分配 7 個 ints. void* p4 = allocator<int>().allocate(7); allocator<int>().deallocate((int*)p4,7); //以下兩函數都是 non-static,定要通過 object 調用。以下分配 9 個 ints. void* p5 = __gnu_cxx::__pool_alloc<int>().allocate(9); __gnu_cxx::__pool_alloc<int>().deallocate((int*)p5,9); #endif
new关键字的实现:
首先new是被编译器编译成三步: Com * p = new Com(1,2); 等价于 : void * mem = ::operator new(sizeof(Com)); // 内存分配 p = static_cast(mem); // 强制类型转换 p->Com::Com(1,2); // 构造函数调用(自己这么写在大部分编译器上不支持,但是实际上只是编译器的实现阻止了这么写)
我们可以知道 new分配内存 是通过 operator new() 函数实现的。
而 operator new() 的函数实现实际上是依靠 malloc 实现的,如下图 :
operator new() 不断地循环调用 malloc(),如若分配内存不成功的话。
但实际上还有另一个操作就是调用 _callnewh(size), 这个函数可以由我们重写。
当malloc也分配不出内存时,就会调用它,我们可以将其重写为 : 释放部分我们认为可以释放的内存,然后下次malloc就能分配到内存了。
而 operator new() 还有第二个参数 : 默认为不报错,如若要报错可以自己指定。
delete 关键字的实现 :
如图所示 : delete 先调用其析构函数,然后再使用 operator delete()释放内存,而 operator delete其实只是简单地调用了free()。