对齐方式有那些_字节对齐不慎引发的挂死问题
前言
之前程序是32位的,切到64位之后,一些隐藏的问题就暴露了。这不,一个由字节对齐导致的挂死问题就出来了。
字节对齐和64位
关于字节对齐,可参考《理一理字节对齐的那些事》,而之前也分享过另一个切64位之后出现的问题,有兴趣的可以查看《记64位地址截断引发的挂死问题》。
本文背景
本文出现的场景是,系统需要解析JSON文件,但是出现部分功能解析正常,部分挂死,并且32位程序正常,而64位程序挂死。鉴于原系统比较复杂,本文将会简化其过程,来看看到底是什么导致了挂死。
本文示例代码主要引自《一个超轻量级的JSON解析器》。
简化后示例代码
//来源:公众号【编程珠玑】
//https://www.yanbinghu.com
#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<string.h>
#pragma pack(1)
#include"cJSON.h"
#pragma pack()/*省略部分代码,完整代码可查看附录部分*/
int main(void)
{char *filename = "./test.json";cJSON *pJson = NULL;cJSON *pTemp = NULL;pJson = prepare_parse_json(filename);if(NULL == pJson){printf("parse json failedn");return -1;}/*获取name值*/pTemp = cJSON_GetObjectItem(pJson,"name");printf("name is %sn",pTemp->valuestring);/*获取site值*/pTemp = cJSON_GetObjectItem(pJson,"site");printf("site is %sn",pTemp->valuestring);/*获取age值*/pTemp = cJSON_GetObjectItem(pJson,"age");printf("age is %dn",pTemp->valueint);/*记得释放相关内存*/cJSON_Delete(pJson);pJson = NULL;return 0;
}
编译运行结果:
$ gcc -L. -o parseJson parseJson.c -lcjson
$ ./parseJson
Segmentation fault (core dumped)
在实际中我们通过GDB观察发现,在解析JSON内部查看JSON数据是完好的,但是调用完解析JSON之后,再去访问使用就不对了,并且我们发现,在不同的功能模块中,调用结果不一样,大部分模块调用并没有任何问题,而只有某个功能模块调用出现问题。
真相
到底是什么导致的呢?
问题的根源在于下面这几行代码:
#pragma pack(1)
#include"cJSON.h"
#pragma pack()
另外补充,cJSON结构体如下:
typedef struct cJSON { //cJSON结构体struct cJSON*next,*prev; /*后驱节点和前驱节点*/struct cJSON *child; /*孩子节点*/int type; /* 键的类型*/char *valuestring; /*字符串值*/int valueint; /* 整数值*/double valuedouble; /* 浮点数值*/char *string; /* 键的名字*/
} cJSON;
#pragma指令说明了按一字节对齐,而cJSON的头文件也在其中,那么就会导致里面的cJSON结构体按照1字节对齐,最终其结构体大小为56个字节而已经编译好的cjson库可并非如此,因此对于64位程序,它还是按照8字节对齐,结构体大小为64字节,而对于32位程序,按照4字节和1字节对齐,都是36字节。
同一个结构体的大小竟然在不同的代码中大小不一样!
最终也就出现了我们遇到的情况,64位程序由于库中申请结构体内存大小与外部调用不一样,最终导致挂死,而32位程序解析JSON正常。
来源:公众号编程珠玑
博客:https://www.yanbinghu.com
总结
幸运的是,本文示例中能够很明显的能看到问题所在,但在实际项目中,如果头文件管理不规范,并且项目的产品多样,通过编译宏来隔开使用的头文件,就很难发现这样的问题。
思考
什么情况下需要1字节对齐呢?
附录
本文完整代码请查看字节对齐不慎引发的挂死问题的附录部分。
微信公众号【编程珠玑】:专注但不限于分享计算机编程基础,Linux,C语言,C++,数据结构与算法,工具,资源等编程相关[原创]技术文章。
对齐方式有那些_字节对齐不慎引发的挂死问题相关推荐
- 字节对齐不慎引发的挂死问题
前言 之前程序是32位的,切到64位之后,一些隐藏的问题就暴露了.这不,一个由字节对齐导致的挂死问题就出来了. 字节对齐和64位 关于字节对齐,可参考<理一理字节对齐的那些事>,而之前也分 ...
- java 字节对齐_字节对齐
字节对齐 为什么字节对齐? 一个字或双字操作数跨越了4字节边界,或者一个四字操作数跨越了8字节边界,被认为是未对齐的,从而需要两次总线周期来访问内存.一个字起始地址是奇数但却没有跨越字边界被认为是对齐 ...
- PyQt5 技术篇-设置alignment对齐方式。Qt Designer设置文本对齐方式。居中、左对齐、右对齐、上对齐、下对齐。
通过 alignment 设置,展开后可以设置水平方向或垂直方向的对齐方式. PyQt5 设置文本对齐方法: self.label.setAlignment(QtCore.Qt.AlignRight| ...
- php设置表格字体对齐方式,Excel 表格字体与对齐方式设置
输入数据后,默认情况下的显示效果是:"常规"格式.11号宋体字.文本左对齐和数字右对齐.而在实际操作中,需要对这些默认的格式进行修改,以满足特定的需要. 设置表格字体 输入数据到单 ...
- java字节对齐原则_C struct 中字节对齐问题
为了提高CPU的存储速度,VC对一些变量的 起始地址做了"对齐"处理.在默认情况下,VC规定各成员变量存放的起始地址相对于结 构的起始地址的偏移量必须为该变量的类型所占用的字节数的 ...
- c语言4字节对齐,理一理C语言字节对齐的那些事
前言 字节对齐是我们初学 C语言 就会接触到的一个概念,但是到底什么是字节对齐?对齐准则又是什么?为什么要字节对齐呢?字节对齐对我们编程有什么启示?本文将简单理一理字节对齐的那些事. 什么是字节对齐 ...
- java label对齐方式_java – 在BorderLayout中对齐JLabel和JTextField
我只是尝试使用一些GUI组件的Java BorderLayout和GridLayout. 我正在尝试右对齐JLabel并左对齐JTextFields,以便它可以更好看. 在setAlignmentX和 ...
- 怎么把位域合成一个字节_C语言中字节对齐和位域
1.1基本类型默认字节对齐和改变字节对齐方式 c语言在给不同类型变量分配地址空间时,并不是总是紧邻着上一个变量的地址空间分配的,而是它所在的地址空间,必须被它的默认对齐字节数整除.例如,int类型占4 ...
- linux下字节对齐
一,内存地址对齐的概念 计算机内存中排列.访问数据的一种方式,包含基本数据对齐和结构体数据对齐. 32位系统中,数据总线宽度为32,每次能够读取4字节数据.地址总线为32,最大寻址空间为4 ...
最新文章
- BZOJ4280 : [ONTAK2015]Stumilowy sad
- 如何统计不重复姓名的个数?
- 跨平台传输中使用base64来保证非ascii码字符串的完整性
- 高并发编程-Thread_正确关闭线程的三种方式
- 【更新】Individual Homework Agile Development reading
- 通过 微软 pai-fs 上传数据到HDFS (Microsoft OpenPAI)
- SQL:postgresql增加自增字段
- sparksql优化_Spark SQL | 目前Spark社区最活跃的组件之一
- 算法:查找序列最小k元素(分治法)
- [有限元方法阶段汇总篇] 有限元入门简单 1D 示例程序(Helmholtz 方程)
- MOS管的工作原理以及设计理念
- 微前端架构实现(项目引入,消息总线,构建部署,监听服务)
- 编译器报错The type of the expression must be an array type but it resolved to int.
- html,css维护优化,网站CSS代码优化的7个原则
- maya2020linux下卸载,卸载产品的步骤 | Maya 2022 | Autodesk Knowledge Network
- Python门面设计模式
- meego linux 双系统,如何安装MeeGo和Windows 7双系统
- linux hub设备,linux usb hub初始化
- TFT液晶屏驱动移植
- 知乎高赞:假如我有500w存进余额宝,可以每天坐着等吃吗?
热门文章
- Policy-based RL小结(Policy Gradient ; Natural policy gradient ;TRPO;ACKTR;PPO )
- 强化学习6——policy gradient的变种State of the Art
- codeforces div2 C. Ehab and a 2-operation task
- python tkinter_Python+tkinter开发一个电子宠物(2 按钮)
- javascript设计模式_开发者都应该了解的7种JavaScript设计模式
- 判断给定的整数数组是不是某二叉搜索树的后序遍历的结果
- python控制语句第一章_【原创】Python第一章
- NAND FLASH 和NOR FLASH工作原理
- 启明云端分享| sigmastar ssd201_ffmpeg移植
- Esp32-CAM(ESP32带camera)使用说明