当前位置:天才代写 > tutorial > C语言/C++ 教程 > C++中new和delete导致的内存分派问题详解

C++中new和delete导致的内存分派问题详解

2017-11-06 08:00 星期一 所属: C语言/C++ 教程 浏览:819

在嵌入式系统中利用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[]操纵符中的个数参数是数组的巨细加上特另外存储工具数目标一些字节。在你的内存分派机制重要思量的这一点。你应该只管制止分派工具数组,从而使你的内存分派计策简朴。

 

    关键字:

天才代写-代写联系方式