1. 程式人生 > >64位系統結構體對齊訪問段錯誤

64位系統結構體對齊訪問段錯誤

先放程式碼:

#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