關於c語言中的位元組對齊padding問題

2021-05-23 05:06:43 字數 829 閱讀 5238

最近的工作中,發現有乙個很奇怪的問題,就是兩個結構體,裡面的字段的值完全是一樣的,但是用memcpy就是不返回0。大致是下面的**:

輸出是:aa != bb

bb != cc

為什麼設的值都是一樣的,但是memcmp就是返回不一樣呢。memcpy還算是乙個比較常用的函式,特別是在c語言中比較乙個有較多字段的結構體,很方便。但是問題往往也就發生在這樣的地方。

這裡先要看下結構體a,一共是7個位元組(以32位平台為例子)。但是編譯器會進行位元組對齊,我用的是vc2008,我不確定預設位元組對齊是什麼,用sizeof(a)來檢視的話會得到8,好了,也就是說最後乙個位元組是編譯器padding上去的,那這個padding上去的值是多少呢?

可以用下面的**來看padding的位元組的值:

從bb的輸出來看padding上去的不是0,而是0xcc。而aa在前面已經用memset設定為0了,所以padding的值也變成0了。

而cc上又變成了0xcd。bb是分配的在棧上的,而cc是通過malloc分配得到的分配在堆上的記憶體,看來記憶體方式分配的不同,還會導致padding不同(但是經過測試,發現相同的記憶體分配方法的話對於同乙個結構體內存是一樣的)。

再來看memcmp(&aa, &bb, sizeof(a));sizeof(a)=8,所以memcmp會去比較8個長度的位元組。所以aa,bb,cc的最後第二個位元組(或最後乙個位元組,取決於記憶體是小端還是大端的)不同,導致memcmp失敗。

從這個例子中可以發現使用memcmp比較特別是結構體的時候還是要十分小心的,最好還是逐個比較欄位來的安全,除非你已經比較熟悉編譯器的行為。雖然是個小錯誤,但是卻很難發現尤其當程式沒有異常結果時,但是卻想一顆定時炸彈一樣隨時會**...

C語言中的位元組對齊

一 什麼是位元組對齊 乙個基本型別的變數在記憶體中占用n個位元組,則該變數的起始位址必須能夠被n整除,即 存放起始位址 n 0,那麼,就成該變數是位元組對齊的 對於結構體 聯合體而言,這個n取其所有基本型別的成員中占用空間位元組數最大的那個 記憶體空間是以位元組為基本單位進行劃分的,從理論上講,似乎...

C語言中的位元組對齊

一 什麼是位元組對齊 乙個基本型別的變數在記憶體中占用n個位元組,則該變數的起始位址必須能夠被n整除,即 存放起始位址 n 0,那麼,就成該變數是位元組對齊的 對於結構體 聯合體而言,這個n取其所有基本型別的成員中占用空間位元組數最大的那個 記憶體空間是以位元組為基本單位進行劃分的,從理論上講,似乎...

c語言中的位元組對齊

一 什麼是位元組對齊?計算機中的資料在儲存時並不是按順序儲存,因為在訪問特定的資料型別時通常從特定的記憶體位址開始,所以資料在儲存時特定的型別儲存時從特定的位址開始,比如我們所說的int型別的對齊數是4,意思是儲存這個int型別的變數的位址 4 0,這就是對齊數為4的意思。二 為什麼要位元組對齊?位...