C++成员变量内存对齐问题,ndk下非对齐的内存访问导致BUS_ADRALN
同样的代码,在vs下运行正常,在android ndk下却崩溃:
signal 7(SIGBUS),code 1 (BUS_ADRALN),fault addr 0xe6b82793
Func(short *pVY[])
{
short *dstY[2] = {pVY[0],pVY[1]};//使用backtrace定位,crash在这一句
}
pVY[0],pVY[1]是从一个统一分配的buffer偏移得来的。
1.考虑内存对齐的原因
pVY[0],pVY[1]:0xee25ffe0,0xee262470 。都是32字节对齐的。
重新分配按64字节对齐,pVY[0],pVY[1]:0xee260600,0xee262b00 ,实际已经256字节对齐了,错误同样出现.
不是pVY[0]和[1]内存没对齐的原因
it appears that SIGBUS 7 is a data misalignment issue, and SIGSEGV 11 is a write to inaccessible memory.
打印出pVY的值为0xe6b82793,正好与fault addr一样,pVY + 1的值为0xe6b82797.
参考:http://stackoverflow.com/questions/13077791/fatal-signal-7-sigbus-at-0x00000000-code-2
Linux操作系统会对于 非对齐内存访问的进程,发送SIGBUS的信号,你的程序,接收到这个信号后,进行coredump,并退出了。
Windows操作系统允许 非地址对齐的内存访问(会损失性能),所以程序在Windows操作系统下,不会出现error。
Win32平台下的微软VC编译器在默认情况下采用如下的对齐规则: 任何基本数据类型T的对齐模数就是T的大小,即sizeof(T)。比如对于double类型(8字节),就要求该类型数据的地址总是8的倍数,而char类型数据(1字节)则可以从任何一个地址开始。Linux下的GCC奉行的是另外一套规则:任何2字节大小(包括单字节吗?)的数据类型(比如short)的对齐模数是2,而其它所有超过2字节的数据类型(比如long,double)都以4为对齐模数。
应该是对pVY,pVY+1的非对齐内存访问造成的,pVY(0xe6b82793)存的是(short*) pVY[0]。
pVY来自class的成员变量:
class A{
...
short *pVY[6];
};
在vs下调试,pVY 为0x001cd9a8,是8字节对齐的。
在ndk下, pVY+0到5为:0xe6b82793,797,79b,79f,7a3,7a7,默认并没有对齐。
解决办法:
1.不进行赋值,函数体内直接使用形参操作:
Func(short *dstY[])
{
for(x = 0;x<w;x++){
dstY[0][x] = x;
dstY[1][x] = x;
}
}
2.设置内存对齐
#pragma pack(push) //保存对齐状态
#pragma pack(8)//设定为4字节对齐
class A{
...
short *pVY[6];
};
#pragma pack(pop)
在ndk下pVY的值为0xe6b82794
C++成员变量内存对齐问题,ndk下非对齐的内存访问导致BUS_ADRALN的更多相关文章
- python 私有和保护成员变量如何实现?—— "单下划线 " 开始的成员变量叫做保护变量,意思是只有类实例和子类实例能访问到这些变量;" 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据
默认情况下,Python中的成员函数和成员变量都是公开的(public),在python中没有类似public,private等关键词来修饰成员函数和成员变量.在python中定义私有变量只需要在变量 ...
- SpringMVC成员变量并发状态下使用测试
1.SpringMVC默认是单例的,使用成员变量在并发状态下该成员变量的值是被共享的 测试平台 我们目前正在开发的电商项目 (架构组成SpringCloud + SpringBoot + Sprin ...
- 【iOS 开发】Objective - C 面向对象 - 方法 | 成员变量 | 隐藏封装 | KVC | KVO | 初始化 | 多态
一. Objective-C 方法详解 1. 方法属性 (1) OC 方法传参机制 Object-C 方法传参机制 : OC 中得参数传递都是值传递, 传入参数的是参数的副本; -- 基本类型 (值传 ...
- Linux内存技术分析(下)
Linux内存技术分析(下) 五.内存使用场景 out of memory 的时代过去了吗?no,内存再充足也不可任性使用. 1.内存的使用场景 page 管理 slab(kmalloc.内存池) 用 ...
- java在继承中父类的成员变量是否会被子类所覆盖
假如 父类 int num =7:子类 int num =9:父类是否会被子类所覆盖? 给你看两个例子: 第一个例子: 第二个例子: 这两个例子的区别只有一句话 由此证明了子类从父类继承的时候 ...
- iOS 成员变量的作用范围
/* 成员变量的作用范围: @public:在任何地方都能直接访问对象的成员变量 @private:只能在当前类的对象方法中直接访问,如果子类要访问需要调用父类的get/set方法 @protecte ...
- java笔记13之成员变量与局部变量
成员变量和局部变量的区别 1在类中的位置不同 局部变量:类的方法体内 成员变量:类的方法之外 2内存的不同位置 局部变量:在栈内存中 成员位置:在堆内存 3生命周期不同 局部变量:随着方法的调用而存在 ...
- 「OC」点语法和成员变量的作用域
一.点语法 (一)认识点语法 声明一个Person类: 1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObje ...
- c++设计成员变量可动态调整的动态类结构
本文主要介绍一下如何使用c++设计成员变量可动态调整的抽象动态类结构.首先介绍一下项目中以前使用的一种类结构:静态类结构 1.静态类结构 很多时候,在项目开发中设计类结构时,我们往往有一种简单.直接的 ...
随机推荐
- Unit05 - 抽象类、接口和内部类(上)
Unit05 - 抽象类.接口和内部类(上) 1.static final常量: 1)必须声明同时初始化 2)通过类名来访问,不能被改变 3)建议:常量名所有字母都大写(多个单词间用_) 4) ...
- Python学习【第二篇】Python入门
Python入门 Hello World程序 在linux下创建一个叫hello.py,并输入 print("Hello World!") 然后执行命令:python hello. ...
- Python开发【第三章】:Python函数介绍
一. 函数介绍 1.函数是什么? 在学习函数之前,一直遵循面向过程编程,即根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复 ...
- dyld: Library not loaded: /System/Library/Frameworks/UserNotifications.framework/UserNotifications解决办法
这个问题产生的原因是:在iOS 10中有UserNotifications这个framework而iOS 9中没有,在iOS 9上运行的时候,会因为找不到而出错. 解决办法是,修改UserNotifi ...
- MyEclipse中无法识别 sun.misc.BASE64Encoder
sun.misc.BASE64Encoder/BASE64Decoder类不属于JDK标准库范畴,但在JDK中包含了该类,可以直接使用.但是在MyEclipse中直接使用却找不到该类. 解决方法: 1 ...
- 关于img 403 forbidden的一些思考
网页中经常需要显示图片给用户看,对网站本身来说有的图片是从本地图片服务器来的,但是一旦数量多了以后,磁盘空间又是一个问题. 所以有时就希望显示其他网站的Image,直接把其他网站的图片显示在我的网站上 ...
- tomcat 大并发报错 Maximum number of threads (200) created for connector with address null and port 8080
1.INFO: Maximum number of threads (200) created for connector with address null and port 8091 说明:最大线 ...
- poj 3617 Best Cow Line
http://poj.org/problem;jsessionid=F0726AFA441F19BA381A2C946BA81F07?id=3617 Description FJ is about t ...
- Iptables防火墙
1 位置 使用vim /usr/sysconfig/iptables 2 启动.关闭.保存 service iptables stop service iptables start service i ...
- android常见问题
1.广播接收器中启动Activity,需要在intent中添加FLAG_ACTIVITY_NEW_TASK /** * Demo描述: * 在BroadcastReceiver中启动Activity的 ...