new和delete导致的内存分配问题详解

2008-02-23 05:27:01来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

在嵌入式系统中使用C 的一个常见问题是内存分配,即对new 和 delete 操作符的失控。

  具备讽刺意味的是,问题的根源却是C 对内存的管理很的容易而且安全。具体地说,当一个对象被消除时,他的析构函数能够安全的释放所分配的内存。这当然是个好事情,但是这种使用的简单性使得程式员们过度使用new 和 delete,而不注意在嵌入式C 环境中的因果关系。并且,在嵌入式系统中,由于内存的限制,频繁的动态分配不定大小的内存会引起很大的问题连同堆破碎的风险。

  作为忠告,保守的使用内存分配是嵌入式环境中的第一原则。

  但当您必须要使用new 和delete时,您不得不控制C 中的内存分配。您需要用一个全局的new 和delete来代替系统的内存分配符,并且一个类一个类的重载new 和delete。

  一个防止堆破碎的通用方法是从不同固定大小的内存持中分配不同类型的对象。对每个类重载new 和delete就提供了这样的控制。

  重载全局的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 allocator
 return (p);
}
void TestClass::operator delete(void *p)
{
 free(p); // Replace this with alternative de-allocator
}

  任何TestClass 对象的内存分配都采用这段代码。更进一步,任何从TestClass 继承的类也都采用这一方式,除非他自己也重载了new 和 delete 操作符。通过重载new 和 delete 操作符的方法,您能够自由地采用不同的分配策略,从不同的内存池中分配不同的类对象。

  为单个的类重载 new[ ] 和 delete[ ] 必须小心对象数组的分配。您可能希望调用到被您重载过的new 和 delete 操作符,但并不如此。内存的请求被定向到全局的new[ ]和delete[ ] 操作符,而这些内存来自于系统堆。

  C 将对象数组的内存分配作为一个单独的操作,而不同于单个对象的内存分配。为了改变这种方式,您同样需要重载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);
 return (p);
}
void TestClass::operator delete[ ](void *p)
{
 free(p);
}
int main(void)
{
 TestClass *p = new TestClass[10];

 // ... etc ...

 delete[ ] p;
}

  但是注意:对于多数C 的实现,new[]操作符中的个数参数是数组的大小加上额外的存储对象数目的一些字节。在您的内存分配机制重要考虑的这一点。您应该尽量避免分配对象数组,从而使您的内存分配策略简单。




标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: 明晰C 内存分配的五种方法的区别

下一篇: C#设计模式之建造者(Builder)模式示例源代码

热门词条
热门标签