对于用户没有定义dctor(包括其所有成员)的类来说, new CLASS[n] 可能会直接请求sizeof(CLASS)*n的空间.

而带有dctor的 类, 因为delete[]的时候要逐个调用析构函数, 要保证调用n次析构.

C++标准没有指定如何具体处理这种情况. 而对于很多数编译器来说, 是在请求的内存前面, 保存对象的个数n(放在其头部).

sizeof(int)  sizeof(CLASS)  ...      
n Object[0] Object[1] Object[2] ... Object[n-1]

on new[]:

1.call CLASS::operator new[], or ::operator new[] ( n*sizeof(CLASS) + sizeof(int) ) to allocate memory

2.write number n to first memory address

3.offset base in sizeof(int), to locate array base(beginning)

4.call ctor for all objects

on delete[] (ptr)

1.real base: offset ptr in -sizeof(int)

2.read the array element count 'n' in real memory base

3.for each object in array ptr, call dctor for 'n' times

4.call CLASS::operator delete[] , or ::operator delete[] (real base) to free memory

基本原理就是上面这样. 对于处理algined的数据, 编译器需要做额外处理:

1. 要求CLASS::operator new[] 分配出的内存已经是对齐的, 编译器假定它分配的是对齐的内存, 也就是说, 用户实现的CLASS::operator new[] , 需要使用对齐分配.

 struct __declspec(align()) Test
{
...
void* operator new[](size_t bytes)
{
return _aligned_malloc(bytes, 16);
}
};

2.sizeof(CLASS) 是对齐后的值, 否则无法保证array中后续所有元素都是对齐的.

3.在上面的基础上, 编译器请求的内存大小有轻微区别:

请求的内存数量稍微偏多:n*sizeof(CLASS) + sizeof(int) =>  n* sizeof(CLASS) + aligned( sizeof(int) )

注意上面, 前后的 sizeof(CLASS) 的值是不一样的, 前者没有对齐, 后者是对齐后的, 也就是说加了alignment以后, sizeof()的值不一样.

4.偏移量也需要对齐, 从而保证偏移以后的base address是对齐的: 即offset不再是sizeof(int), 而是aligned(sizeof(int))

这样可以保证最终使用的数组是对齐的.

aligned( sizeof(int) )  sizeof(CLASS) : aligned  ...      
n Object[0] Object[1] Object[2] ... Object[n-1]

 

上面的除了operator new[] 需要用户实现以外, 编译器都会把剩余的工作做完.

经过测试MSVC11和MinGW GCC 4.8 都是没有问题的.

但是在android的GCC4.6上是有bug的, offset忽略了对齐的问题, 使用了固定偏移量8. 解决方y法是hack, 在operator new[]/delete[]里面手动处理offest.

[工作积累] GCC 4.6 new[] operator内存对齐的BUG的更多相关文章

  1. Windows+GCC下内存对齐的常见问题

    结构/类对齐的声明方式 gcc和windows对于modifier/attribute的支持其实是差不多的.比如在gcc的例子中,内存对齐要写成: class X { //... } __attrib ...

  2. struct内存对齐1:gcc与VC的差别

    struct内存对齐:gcc与VC的差别 内存对齐是编译器为了便于CPU快速访问而采用的一项技术,对于不同的编译器有不同的处理方法. Win32平台下的微软VC编译器在默认情况下采用如下的对齐规则:  ...

  3. GNU C - 关于8086的内存访问机制以及内存对齐(memory alignment)

    一.为什么需要内存对齐? 无论做什么事情,我都习惯性的问自己:为什么我要去做这件事情? 是啊,这可能也是个大家都会去想的问题, 因为我们都不能稀里糊涂的或者.那为什么需要内存对齐呢?这要从cpu的内存 ...

  4. 重磅硬核 | 一文聊透对象在 JVM 中的内存布局,以及内存对齐和压缩指针的原理及应用

    欢迎关注公众号:bin的技术小屋 大家好,我是bin,又到了每周我们见面的时刻了,我的公众号在1月10号那天发布了第一篇文章<从内核角度看IO模型的演变>,在这篇文章中我们通过图解的方式以 ...

  5. 虚函数列表: 取出方法 // 虚函数工作原理和(虚)继承类的内存占用大小计算 32位机器上 sizeof(void *) // 4byte

    #include <iostream> using namespace std; class A { public: A(){} virtual void geta(){ cout < ...

  6. C/C++: C++位域和内存对齐问题

    1. 位域: 1. 在C中,位域可以写成这样(注:位域的数据类型一律用无符号的,纪律性). struct bitmap { unsigned a : ; unsigned b : ; unsigned ...

  7. C结构体中数据的内存对齐问题

    转自:http://www.cnblogs.com/qwcbeyond/archive/2012/05/08/2490897.html 32位机一般默认4字节对齐(32位机机器字长4字节),64位机一 ...

  8. C语言 结构体的内存对齐问题与位域

    http://blog.csdn.net/xing_hao/article/details/6678048 一.内存对齐 许多计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地 ...

  9. c++中类对象的内存对齐

    很多C++书籍中都介绍过,一个Class对象需要占用多大的内存空间.最权威的结论是: *非静态成员变量总合.(not static) *加上编译器为了CPU计算,作出的数据对齐处理.(c语言中面试中经 ...

随机推荐

  1. Yii 增删改查 测试记录

    亲们, 我是yii小白 不要笑话我奥.今天白天写一个管理模块涉及到 yii ar 下的  curd 操作,做 update 操作时纠结了好久,今天晚上花点时间学习, 下面写下我的测试记录 代码如下: ...

  2. js 将json字符串转换为json兑现

    在数据传输过程中,json是以文本,即字符串的形式传递的,而JS操作的是JSON对象,所以,JSON对象和JSON字符串之间的相互转换是关键.例如:JSON字符串:var str1 = '{ &quo ...

  3. c#反射机制学习和利用反射获取类型信息

    反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的 ...

  4. SRF之数据访问

    数据访问组件实现实体类和数据表映射.SQL语句配置执行.动态sql语句等功能,ORM方式能实现简单的对象和表的映射(配置类似hibernate),但比较单一(不支持一对多.多对多的情况),下边不做介绍 ...

  5. Microsoft SqlServer2008技术内幕:T-Sql语言基础-读书笔记1

    一.理论背景:关系模型,其数学理论是集合论和谓词逻辑. 1.集合论:集合定义是把我们直观或思维中确定的,相互间有明确区别的那些对象视为一个整体,这个整体就是集合. 2.谓词逻辑:谓词是判断对象是否有某 ...

  6. Postgresql命令行和数据库备份与恢复

    进入Postgresql   1 进入数据库   默认安装会创建postgres 用户,,使用postgres用户,psql命令会直接进入数据库: Bash代码   $ su postgres     ...

  7. 【转】oracle connect by用法

    今天偶然看到connect by,但记不太清楚具体用法了.转了个博客(写的蛮好的),当作笔记. http://www.cnblogs.com/linjiqin/p/3152690.html 先用sco ...

  8. Android--获取App应用程序的大小

    Android对这种方法进行了封装,我们没有权限去调用这个方法,所以我们只能通过AIDL,然后利用Java的反射机制去调用系统级的方法. 下面上代码:(注释比较详细) /** * 作用:-----获取 ...

  9. [SRH.Docker] HBase Java 第一天学习记录

    主要对HBase Table 的 简单操作, 直接上代码吧!!! http://pan.baidu.com/s/1hqzTTze       ui92

  10. 禁用DropDownList的Items

    可以先看看效果,被禁用的DropDownList的Items已经无法选取与颜色也变为灰色. 刚开始,DropDownList没有接收从网址传来的参数时,它每一个Item都是可以选取的,一旦接收了值.所 ...