C語言指標加1問題以及位元組對齊問題

2022-05-05 08:36:12 字數 1176 閱讀 5462

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

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

我的**裡有兩個結構體,假設為結構體head和結構體data,其結構如下:

struct

data;

struct

head;

其中,結構體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;45

for(size_t i=0;ifieldcount;++i)

6

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位元組對齊的時候,如果取得時候沒有宣告對齊,那會存在意想不到的效果,哈哈聰明的你可以嘗試,反正我是嘗試過了。

c語言位元組對齊問題(一)

在這裡只總結結構體的位元組對齊問題,看下面的結構體 struct s1 char a int b short c struct s2 char a short c int b 那麼sizeof s1 12,sizeof s1 8 我們可以假定結構體在記憶體中的位址是0x0000開始的,那麼我們說的位...

c語言位元組對齊問題(二)

struct s 那麼sizeof s 4 先說下位域在記憶體對齊的一些規則 2.位域的多少定義多少就後面接多少位,但是位域要求是連續的位元組,像a已經占有4位了,乙個位元組8位,那麼就會填補4位,到下個位元組,所以到b變數占用的是另個一新位元組。3.對於一些資料說位域不能跨兩個位元組,就是說位域長...

C語言位元組對齊問題詳解

引言 考慮下面的結構體定義 typedef struct t foo int main void 複製 執行後輸出 c1 0,s 2,c2 4,i 8為什麼會這樣?這就是位元組對齊導致的問題。一 什麼是位元組對齊 現代計算機中,記憶體空間按照位元組劃分,理論上可以從任何起始位址訪問任意型別的變數。但...