这是2013年写的一篇旧文,放在gegahost.net上面 http://raison.gegahost.net/?p=15

February 15, 2013

How `new’ operator works ?

Filed under: c++ — Tags: C++ internal, c++ memory layout, c++ new, POD, virtual class — Raison @ 12:38 am

(original works by Peixu Zhu)

For single inherited classes

1.  in case of single instance of a class without virtual method (inherited or not).

  • suppose the class is `theClass‘.
  • at first, it calls function `malloc‘ to allocate sizeof(theClass) memory, the size is always the same to POD structures.
  • if the `malloc‘ function fails, throw exception if `nothrow‘ is not specified.
  • if the `malloc‘ function success, call class initializer and internal initializer to set default values of members( to be zeros)
  • call the constructor on the instance as a chain, the most rooted constructor is called at first, and then the derived constructors, the latest is theClass‘s constructor.
  • set return value to be the address of `malloc‘ returned.

2.  in case of single instance of a class with virtual method (inherited or not).

  • at first, it calls functon `malloc‘ to allocate sizeof(theClass) sized memory, for single inherited class, sizeof(theClass) =  (sizeof(void*) )  +  sizeof(POD structure). the additional (sizeof(void*) ) sized memory is for purpose of storing virtual pointer table for the class and it’s parent classes.
  • if the `malloc‘ function fails, throw exception if `nothrow‘ is not specified.
  • if the `malloc‘ function success, at first, set the first (sizeof(void*)  to be the class’s virtual pointer table, and then call class initializer and  internal initializer to set default values of members( to be zeros) on subsequent memory.
  • call the constructor on the instance as a chain, the most rooted constructor is called at first, and then derived classes’ constructors, the latest is the class’s constructor.
  • set return value to be the address of `malloc‘ returned.

3.  in case of arrayed instances of a class without virtual method.

  • suppose n instances are required.
  • calculate the size of required memory:  sizeof(void*) + n * sizeof(theClass)
  • call `malloc‘ to allocate memory of the size required.
  • if `malloc‘ fails, throw exception if `nothrow‘ is not specified.
  • if `malloc‘ success, set the first sizeof(void*) the count of instances in the array (i.e. `n’).
  • for subsequent memory,  each instance is initialized and constructed as above .
  • set return value to be the address of `malloc‘ returned minus sizeof(void*), i.e., the address of first instance.

4.  in case of arrayed instances of a class with virtual method.

  • calculate the size of required memory:

sizeof(void*) + n * sizeof(theClass).
sizeof(theClass) = sizeof(void*) + sizeof(POD)

  • call `malloc‘ to allocate the size required.
  • if `malloc‘ fails, throw exception if `nothrow‘ is not specified.
  • if `malloc‘ success, set the first sizeof(void*) the count of instances in the array (i.e. `n’).
  • for subsequent memory, for each instance, set the first
    sizeof(void*) memory to be the address of virtual pointer table of the
    class, then initialize the members, and call constructor one  by one.
  • set return value to be the address of `malloc‘ returned minus sizeof(void*), i.e., the address of first instance.

5.  about the virtual pointer table.

  • the layout of virtual pointer table:

[vdes1][vdes2](vm1)(vm2)(vm3…)[typeinfo [data of typeinfo]].
square bracketing indicates optional.
each elements are pointer to functions/methods.
vdes1 and vdes2 are virtual destructor.
vm1/vm2 … are virtual methods.
typeinfo    for function `typeid‘ (std::type_info)
data of typeinfo is the data of std::type_info

  • if the class is virtual, then there is typeinfo, and data of typeinfo.
  • if the class has virtual desctructor, there’s vdes1 and vdes2. one is called by `delete‘ operator (free memory in function), and ther other one is called by `delete[]‘ operator (does not free memory in function).
  • in runtime environment, calling virtual methods are converted into
    referencing index in the virtual pointer table, the index value of each
    virtual method is determined at compiling time. In derived classes, the
    child class instance and parent class instance share the same index
    value on same virtual method (with same mangling signature). If the
    child class does not override the parent virtual method, it will set the
    indexed pointer to the parent’s method, rather than of the child,
    however, if the child class override the virtual method, it will be  the
    indexed with pointer to the child’s method.

6.  about the alignment of  address returned by `new/new[]’ operator.
As you know, `new‘ and `new[]‘ operator both call `malloc‘ function to allocate memory required, thus, the alignment of address returned by `new‘ or `new[]‘ is determined by the address returned by `malloc‘. `mallocdoes not guarantee the returned address is aligned well, thus, the `new‘ and `new[]‘ also do not guarantee the returned address is aligned well, though the size of the class is aligned.
But, there’s alignment version of `malloc‘, like posix_memalign, or valloc, etc., how about alignment version of `new‘ and `new[]‘ ?  The replacement new operator in C++11 may solve the problem.

For classes with multiple parent classes.
1. each parent class has an instance in the derived class instance, sequenced as the class definition.

2. the derived class’s own members are placed at the tail of the allocated memory.

3. sizeof(theClass) = sizeof(parentClass) * (count of parent classes) + sizeof(own)

4. for plain classes without virtual methods, sizeof(own) = sizeof(POD structure),  and for classes with virtual methods, sizeof(own) = sizeof(void*) + sizeof(POD structure).

How `new’ operator works ?的更多相关文章

  1. CLR via C# 3rd - 04 - Type Fundamentals

    1. System.Object        The runtime requires every type to ultimately be derived from the System.Obj ...

  2. Flink - Working with State

    All transformations in Flink may look like functions (in the functional processing terminology), but ...

  3. Think Python - Chapter 11 - Dictionaries

    Dictionaries A dictionary is like a list, but more general. In a list, the indices have to be intege ...

  4. MDX : Non Empty v/s NonEmpty

    MDX : Non Empty v/s NonEmpty User Rating: / 50 PoorBest Written by Jason Thomas    Friday, 07 May 20 ...

  5. NonEmpty和Non Empty的区别[转]

    One of my favourite questions in MDX is the difference between Non Empty and NonEmpty because even t ...

  6. JsonPath详解

    JsonPath is to JSON what XPATH is to XML, a simple way to extract parts of a given document. JsonPat ...

  7. C++11 : variadic templates(可变参数模板)

      Introduction: Before the possibilities of the new C++ language standard, C++11, the use of templat ...

  8. ADF BC New Features

      Examining ADF Business Components New Features Purpose In this tutorial, you create a series of si ...

  9. Dart语言特性必备了解!

    学习Dart语言,必须将以下的概念熟记于心: 在dart语言中,一切皆为对象.所有的对象都是一个类的实例.甚至整数.函数.null也看做是对象.所有的对象都继承于Object类 尽管Dart是强类型语 ...

随机推荐

  1. WAS:启动服务后,server一会挂起。

    有个WAS集成,其中一台因为linux系统异常需要重新安装,于是服务器停了:一会现场提报ERP系统访问不了. 查看了另外一个server后台日志,有一批webcontainer进程挂起,明显服务死了. ...

  2. hdu 2594 Simpsons’ Hidden Talents(两个串的next数组)

    题意:两个字符串s.t,求s和t的最长的相同的前缀和后缀 思路:先求s的next数组,再求t的next数组(即代码中ex数组,此时不是自己与自己匹配,而是与s匹配),最后看ex[len2]即可(len ...

  3. 【opencv】opencv在图片、视频嵌中英文字符的方法

    转自:http://www.cnblogs.com/hujingshuang/p/5119015.html 说明:本博文是根据前人已有的成果并结合自己的理解而成的.为了避免让读者感到繁琐,我将运用小学 ...

  4. 出现Insufficient space for shared memory file错误解决

    今天在linux下敲命令,出现上面的错误,原来是临时文件目录(/tmp)下的空间不够了,df一看/下100%了.

  5. NOIP2005题解

    传送门 考查题型 dp 模拟 贪心 T1 谁拿了最多的奖学金 题目描述 某校的惯例是在每学期的期末考试之后发放奖学金.发放的奖学金共有五种,获取的条件各自不同: 1) 院士奖学金,每人8000元,期末 ...

  6. 将svn的项目转移到另外一个仓库中

    前几天在做一个项目的时候,因为需要,需要将Server A 上SVN仓库 repos1中的项目pro1迁移到Server B 上的SVN仓库中,首先想到的是:通过复制,但是仔细一想,这样是不可能的:然 ...

  7. uploadify提示修改为中文

    使用uploadify时报错时是英文提示,并且上传文件进度条显示的是英文,如何修改为中文呢,直接打开jquery.uploadify.min.js(如果你使用的是jquery.uploadify.js ...

  8. F - Candy Bags

    A. Candy Bags time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  9. Windows远程服务器不能复制粘贴

    操作步骤: 在服务器上打开任务管理器,查看进程,有 rdpclip.exe 进程,关闭此进程: 然后 开始->运行->rdpclip.exe 重新运行此程序,恢复正常.

  10. 怎样在github上协同开发

    How to co-work wither parter via github. Github协同开发情景模拟 Github不仅有很多开源的项目可以参考,同样也是协同开发的最佳工具,接下来的就模拟一下 ...