C++内存函数
Malloc和Free
这是C语言使用的函数,只能从默认堆中分配内存,并且只是分配内存,不能调用构造函数,且只是按字节分配,不能按类型分配。
New 和Delete
这是C++语言使用的函数,默认情况下从默认堆中分配内存,但是也可以通过重载New函数,从自建堆中按类型分配;同时可以执行构造函数和析构函数。它底层是通过HeapAlloc和HeapFree实现的。 依赖于编译器的实现。
GlobalAlloc 和GlobalFree
这是比HeapAlloc和HeapFree更慢的函数,但是也没有比它们更好的优点,只能在默认堆中分配;16位操作系统下利用它们分配内存。
LocalAlloc和LocalFree
在WindowsNT 内核里,和GlobalAlloc、GlobalFree是一样的。
· 一个例子
默认情况下,New关键字是利用HeapAlloc在默认堆上建立对象。本文重载了类的New方法,使得类在自己的堆中存放,这样可以与外面的对象隔离,以免重要的数据结构被意外破坏。由于类中的成员变量是在堆中存放,因此不局限于线程堆栈的1M空间。
C++程序如下:
class AllocateInOtherHeap
{
public:
AllocateInOtherHeap(void);
~AllocateInOtherHeap(void);
void* operator new(size_t size);
static HANDLE heap;
public:
//类对象唯一所需的空间
int iArray[1024*1024*10];
AllocateInOtherHeap::AllocateInOtherHeap(void)
{
cout<<"AllocateInOtherHeap()"<<endl;
//如果New函数没有分配够空间,那么此处会出现访问违规
memset(iArray,0,sizeof(AllocateInOtherHeap));
iArray[1024]=8;
}
void* AllocateInOtherHeap::operator new(size_t size)
{
if(heap==NULL)
heap=HeapCreate(HEAP_NO_SERIALIZE|HEAP_GENERATE_EXCEPTIONS,1024*1024*10,0);
//分配足够这个类对象的空间
void* p=HeapAlloc(heap,0,sizeof(AllocateInOtherHeap));
cout<<"堆的大小="<<HeapSize(heap,0,p)<<endl;
printf("AllocateInOtherHeap堆地址=%x\n",heap);
printf("AllocateInOtherHeap返回地址=%x\n",p);
return p;
}
AllocateInOtherHeap::~AllocateInOtherHeap(void)
{
cout<<"~AllocateInOtherHeap"<<endl;
}
void AllocateInOtherHeap::operator delete(void* p)
{
HeapFree(heap,0,p);
HeapDestroy(heap);
cout<<"delete()"<<endl;
}
};
结果如下:
可见,new函数先分配够空间,然后才能初始化对象变量;而delete函数得先做析构,才能释放空间。对象保存在堆外,因为大于512K;对象大小刚好是iArray变量的大小。
注意,如果没有分配足够的空间,虽然你可以得到对象指针,但是你访问数据时可能会出现访问违规,如果没出现,那更惨,意味着你读写了别人的数据。