日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

对齐方式有那些_字节对齐不慎引发的挂死问题

發布時間:2024/10/8 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对齐方式有那些_字节对齐不慎引发的挂死问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

之前程序是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++,數據結構與算法,工具,資源等編程相關[原創]技術文章。

總結

以上是生活随笔為你收集整理的对齐方式有那些_字节对齐不慎引发的挂死问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。