2.2、控制 C++的内存分配
在嵌入式系统中使用 C++的一个常见问题是内存分配,即对 new 和 delete 操
作符的失控。
具有讽刺意味的是,问题的根源却是 C++对内存的管理非常的容易而且安全。
具体地说,当一个对象被消除时,它的析构函数能够安全的释放所分配的内存。
这当然是个好事情,但是这种使用的简单性使得程序员们过度使用 new 和
delete,而不注意在嵌入式 C++环境中的因果关系。并且,在嵌入式系统中,由
于内存的限制,频繁的动态分配不定大小的内存会引起很大的问题以及堆破碎的
风险。
作为忠告,保守的使用内存分配是嵌入式环境中的第一原则。
但当你必须要使用 new 和 delete 时,你不得不控制 C++中的内存分配。你需要
用一个全局的 new 和 delete 来代替系统的内存分配符,并且一个类一个类的重
载 new 和 delete。
一个防止堆破碎的通用方法是从不同固定大小的内存持中分配不同类型的对象。
对每个类重载 new 和 delete 就提供了这样的控制。
2.2.1、重载全局的 new 和 delete 操作符
可以很容易地重载 new 和 delete 操作符,如下所示:
void* operator new(size_t size){
void*p =malloc(size);return(p);
}
void operator delete(void*p){
free(p);
}
这段代码可以代替默认的操作符来满足内存分配的请求。出于解释 C++的目的,
我们也可以直接调用 malloc() 和 free()。
也可以对单个类的 new 和 delete 操作符重载。这是你能灵活的控制对象的内存
分配。
class TestClass{
public:
void* operator new(size_t size);
void operator delete(void*p);// .. other members here ...
};
void* TestClass::operator new(size_t size){
void *p =malloc(size);// Replace this with alternative allocatorreturn(p);
}
void TestClass::operator delete(void*p){
free(p);// Replace this with alternative de-allocator
}
所有 TestClass 对象的内存分配都采用这段代码。更进一步,任何从 TestClass 继
承的类也都采用这一方式,除非它自己也重载了 new 和 delete 操作符。通过
重载 new 和 delete 操作符的方法,你可以自由地采用不同的分配策略,从不
同的内存池中分配不同的类对象。