64位系統結構體對齊訪問段錯誤
阿新 • • 發佈:2019-01-31
先放程式碼:
#include struct s { char c; int b; }; int main(void){ printf("sizeof (struct s) = %d.\n",sizeof(struct s)); struct s s1; s1.c = 'g'; s1.b = 66; char *p1 = (char *)(int)(&s1); printf("*p1 = %c.\n", *p1); // g int *p2 = (int *)((int)&s1 + 1); printf("*p2 = %d.\n", *p2); // 亂碼 int *p3 = (int *)((int)&s1 + 4); printf("*p3 = %d.\n", *p3); // 66 }
這是一個簡單的結構體對齊的例子,筆者在unbuntu 64位下執行的時候卻老是出現段錯誤:
在VS2015中測試:
x86狀態(即32位環境):
X64環境:
執行出現了錯誤,筆者經過除錯後發現,64位下&a指標型別為8位元組,用int強制轉化值只截取了4位元組會導致錯誤,
linux下修改程式碼如下:
#include <stdio.h>
struct s {
char c;
int b;
};
int main(void){
printf("sizeof (struct s) = %ld.\n",sizeof(struct s));
struct s s1;
s1.c = 'g';
s1.b = 66;
char *p1 = (char *)(long)(&s1);
printf("*p1 = %c.\n", *p1);// g
int *p2 = (int *)((long)&s1 + 1);
printf("*p2 = %d.\n", *p2);// 亂碼
int *p3 = (int *)((long)&s1 + 4);
printf("*p3 = %d.\n", *p3);// 66
}
結果:
要是在VS2015中x64執行需要將long改成long long型。
感悟:在32位和64位系統以及不同的編譯環境下面的結構各不相同,在以後學習過程中要多多注意,下面筆者列出VS2015和linux下各種資料型別長度,以供參考~
資料型別 | 32位 | VS2015(64位) | Linux(64位) |
---|---|---|---|
short | 2 | 2 | 2 |
char | 1 | 1 | 1 |
int | 4 | 4 | 4 |
float | 4 | 4 | 4 |
long | 4 | 4 | 8 |
long long | 8 | 8 | 8 |
double | 8 | 8 | 8 |
void * | 4 | 8 | 8 |