当前位置:  编程技术>c/c++/嵌入式

operator new在C++中的各种写法总结

    来源: 互联网  发布时间:2014-10-19

    本文导语:  乍一看,在C++中动态分配内存很简单:new是分配,delete是释放,就这么简单。然而,这篇文章讲得要复杂一点,并且要考虑到自定义层次。这也许对简单的程序并不重要,但对你在代码中控制内存却是十分必要的,是否能写一...

乍一看,在C++中动态分配内存很简单:new是分配,delete是释放,就这么简单。然而,这篇文章讲得要复杂一点,并且要考虑到自定义层次。这也许对简单的程序并不重要,但对你在代码中控制内存却是十分必要的,是否能写一个自定义的分配器,某种高级内存管理表或一个特定的垃圾回收机制。

这篇文章并不是一个综合的手册,而是一个C++中各种内存分配方法的概述。它面向已经很熟悉C++语言的读者。

原生operator new

我们先从原生operator new开始。考虑如下代码,它用来分配5个int型的空间并返回指向他们的指针[1]:

int* v = static_cast(::operator new(5 * sizeof(*v)));

当像如上的调用,operator new扮演原生的内存分配角色,类似malloc。上面等价于:

int* v = static_cast(malloc(5 * sizeof(*v)));

释放用operator new分配的内存用operator delete:

::operator delete(v);

你愿意永远用原生new和delete函数吗?是,只在极少数不用,我在下面的文章中会论证的。为什么用它们而不用原来的可信的malloc和free呢?一个很充分的原因就是你想保持代码在C++领域的完整性。混合使用new和free(或malloc和delete)是很不可取的(big NO NO)。用new和delete的另一个原因是你可以重载(overload)或重写(override)这些函数,只要你需要。下面是个例子:

代码如下:

void* operator new(size_t sz) throw (std::bad_alloc)
{
    cerr ~Foo();
  operator delete(p);
}

这时正适合我重复这篇文章第一段提到的,如果一个类有它自己的operator new或 operator delete,这些函数将被调用,而不是调用全局的函数来分配和收回内存。

Placement new
现在,回来我们上面看到样例代码中的"placement new"问题。它恰好真的能用在C++代码中的语法。首先,我想简单地解释它如何工作。然后,我们将看到它在什么时候有用。

直接调用 placement new会跳过对象分配的第一步。也就是说我们不会向操作系统请求内存。而是告诉它有一块内存用来构造对象[3]。下面的代码表明了这点:

代码如下:

int main(int argc, const char* argv[])
{
    // A "normal" allocation. Asks the OS for memory, so we
    // don't actually know where this ends up pointing.
    //一个正常的分配。向操作系统请求内存,所以我们并不知道它指向哪里
    int* iptr = new int;
    cerr ~Foo();
对,显式调用析构函数在C++中是合法的,并且这也是唯一一种正确的做法[5]。

结论
这是一个复杂的主题,并且这篇文章只起到一个介绍的作用,对C++的多种内存分配方法给出了一种“尝鲜”。一旦你研究一些细节会发现还有许多有趣的编程技巧(例如,实现一个内存池分配)。这些问题最好是在有上下文的情况下提出,而不是作为一个普通的介绍性文章的一部分。如果你想知道得更多,请查阅下面的资源列表。

资源
· C++ FAQ Lite, especially items 11.14 and 16.9

·  "The C++ Programming Language, 3rd edition" by Bjarne Stroustrup – 10.4.11

· "Effective C++, 3rd edition" by Scott Myers – item 52

·  "Modern C++ Design" by Andrei Alexandrescu – chapter 4

· Several StackOverflow discussions. Start with this one and browse as long as your patience lasts.

我仍会在operator new前面显式地写::(双冒号),虽然这里并不是必须的。恕我直言,这是一个很好的做法,特别当在重载operator new的类中,可以避免二义性。

[2]

注意到这里是检查是否为NULL。这样做使delete p 很安全,即使p是NULL。

[3]

对传给placement new的指针确保有足够的内存分配给对象,并且确保它们正确地对齐,这都是你的应该做的。

[4]

内存池本身是一个很大且迷人的话题。我并不打算在这里扩展,所以我鼓励你自己上网找些信息,WIKI如往常一样是个好地方(good start)。

[5]

事实上,标准的vector容器用这种方法去析构它保存的数据。


    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • java命名空间java.rmi.server类operation的类成员方法: operation定义及介绍
  • 书不在 <jsp:forward page="/landmis/operation/OfficeTaskList.jsp"/> 是啥意思
  • java命名空间java.lang类character.unicodeblock的类成员方法: mathematical_operators定义及介绍
  • basic linux operation 都有什么?
  • java命名空间javax.xml.ws.handler接口messagecontext成员方法: wsdl_operation定义参考
  • connect failed:Operation now in progress?
  • java命名空间java.lang.management类managementfactory的类成员方法: operating_system_mxbean_name定义及介绍
  • 1254-055 Dependency line needs colon or double colon operator
  • java命名空间javax.print.attribute.standard类jobstatereason的类成员方法: job_canceled_by_operator定义及介绍
  • 是否内核里面的模块里面都有一个file_operations结构???
  • java命名空间java.rmi.server类operation的类成员方法: tostring定义及介绍
  • 读file_operation结构体遇到的问题
  • 请教:TCP CONNECT失败,返回错误Operation now in progress
  • 紧急求助 我的系统总是出现 missing operating system
  • 请问用户态与驱动传参数除了用file_operations这个结构外还有其他方法么
  • 求助一个debian系统安装问题“error loading operating system”
  • Web服务器/前端 iis7站长之家
  • inode,file,file_operations类型问题
  • 关于g++ 下的undefined operator new [] (unsigned long) 的错误
  • 谁有Network Administration for the Solaris 10 Operating System (SA-300-S10)电子版?感谢共享
  • Some questions about operation of Linux.




  • 特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3