C語言指針加1問題以及字節對齊問題


今天早上自己寫了一段代碼,然后測試的時候發現結果總是和預期的不一樣,而且偏差的有點離譜,冥思苦想了將近五個小時,最后在我要開始懷疑人生的時候,發現原來是自己犯了一個極其低級但又容易被忽略的問題。好吧,我承認我有點丟程序員的人了。

廢話不多說,直接開始用例子來說明吧:

我的代碼里有兩個結構體,假設為結構體Head和結構體Data,其結構如下:

struct Data{
     int a;
     char b;
     short c;
     long d;    
};

struct Head{
     int fieldcount;
     Data fielddata[1];
};

其中,結構體Head包含結構體Data的指針,且fieldcount表示后續有多少Data。我是將這個數據存儲在緩沖區中(假設緩沖區為char buf[1024])。當我通過如下代碼取數據的時候,發現取出來的數據結構體Data完全不是自己要的:

1         Head* h = (Head*) (buf+offset);
2         size_t datalen = sizeof (Head) + (h->fieldcount-1) * sizeof (Data);
3         offset += datalen;
4 
5         for(size_t i=0;i<h->fieldcount;++i)
6         {
7             Data* data=(Data*)(h+sizeof(Head)+(i-1)*sizeof(Data));
8             printf("a: %d b: %c \n", data->a,data->b);
9         }

不知道大家看出來問題沒有,我竟然研究這一段這么簡單的代碼研究了五個小時,簡直丟人啊。直接說問題吧。問題出在這句代碼:

1 Data* data=(Data*)(h+sizeof(Head)+(i-1)*sizeof(Data));

我的本意是想依次取出來Head后面的data的,即通過Data指針操作內存。可是我卻忘記了(指針+偏移量)的含義了。這里的偏移量看起來很正確,是以字節為單位的數,其實對於指針來說,是加了偏移量*sizeof(Head)的字節數,這里的偏移量,意思是加了多少個Head,這也是指針的奇妙之處,也是平時容易忽略的地方。所以每次我讀Data的時候,總是讀的很靠后面的內存,到時候讀的數據存在問題。修改后的代碼如下:

1 Data* data=(Data*)((char*)h+sizeof(Head)+(i-1)*sizeof(Data));

當然,我的環境是在linux上,以utf-8為編碼格式,所以char是一個字節,當然這里具體環境可以修改代碼。

 

 

溫馨提示:

在調試代碼的時候,還發現一個容易出錯的地方,就是注意字節對齊問題。當你把數據存到緩沖區時,如果數據是字節對齊,例如以1字節對齊的時候,如果取得時候沒有聲明對齊,那會存在意想不到的效果,哈哈聰明的你可以嘗試,反正我是嘗試過了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM