程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 內存對齊(字節對齊、結構體對齊)

內存對齊(字節對齊、結構體對齊)

編輯:C++入門知識

搜索:“內存對齊”、“字節對齊”、“結構體對齊”
Example-01:
[cpp]
#include <stdio.h> 
 
typedef struct 

    int     a; 
    char    b; 
    int     c; 
} Test1; 
 
typedef struct 

    char    a; 
    int     b; 
    char    c; 
} Test2; 
 
typedef struct 

    int     a; 
    char    b[9]; 
    int     c; 
} Test3; 
 
int main() 

    Test1   t1; 
    Test2   t2; 
    Test3   t3; 
    int     a; 
    char    b; 
    char    b2[9]; 
    int     c; 
    printf("Test1: %d\n", sizeof(Test1)); 
    printf("Test1: %d\n", &t1); 
    printf("Test1.a: %d\n", &t1.a); 
    printf("Test1.b: %d\n", &t1.b); 
    printf("Test1.c: %d\n", &t1.c); 
 
    printf("Test2: %d\n", sizeof(Test2)); 
    printf("Test2: %d\n", &t2); 
    printf("Test2.a: %d\n", &t2.a); 
    printf("Test2.b: %d\n", &t2.b); 
    printf("Test2.c: %d\n", &t2.c); 
 
    printf("Test3: %d\n", sizeof(Test3)); 
    printf("Test3: %d\n", &t3); 
    printf("Test3.a: %d\n", &t3.a); 
    printf("Test3.b: %d\n", t3.b); 
    printf("Test3.c: %d\n", &t3.c); 
 
    printf("a: %d\n", &a); 
    printf("b: %d\n", &b); 
    printf("b2: %d\n", b2); 
    printf("c: %d\n", &c); 
    return 0; 

/*
VC++ 6.0:
Test1: 12
Test1: 1245044
Test1.a: 1245044
Test1.b: 1245048
Test1.c: 1245052
Test2: 12
Test2: 1245032
Test2.a: 1245032
Test2.b: 1245036
Test2.c: 1245040
Test3: 20
Test3: 1245012
Test3.a: 1245012
Test3.b: 1245016
Test3.c: 1245028
a: 1245008
b: 1245004
b2: 1244992
c: 1244988
 
gcc:
Test1: 12
Test1: 2293572
Test1.a: 2293572
Test1.b: 2293576
Test1.c: 2293580
Test2: 12
Test2: 2293560
Test2.a: 2293560
Test2.b: 2293564
Test2.c: 2293568
Test3: 20
Test3: 2293540
Test3.a: 2293540
Test3.b: 2293544
Test3.c: 2293556
a: 2293536
b: 2293535
b2: 2293526
c: 2293520
*/ 
存儲布局圖如下:


Example-02(改編自《C陷阱與缺陷》4.4):
[cpp]
#include <stdio.h> 
int main() 

    int i; 
    char c; 
    int j; 
    printf("i address:%d\n",&i); 
    printf("c address:%d\n",&c); 
    printf("j address:%d\n",&j); 
    for(i=0 ; i<5; i++) 
    { 
        scanf("%d",&c); 
        printf("%d ",i); 
    } 
    return 0; 

/*
gcc:
i address:2293580
c address:2293579
j address:2293572
3
0 3
0 3
0 3
0 100000
390
 
VC++ 6.0:
i address:1245052
c address:1245048
j address:1245044
3
0 10000
1 3000
2 333333333333
3 333
4
*/ 
這段程序在用VC編譯運行時沒問題的,但是用gcc編譯運行是有問題的,原因是因為 i 的前3個字節的內存被 scanf() 輸入的整數的後三個字節覆蓋導致的,內存布局圖見上圖:

Example-01, Example-02 小結:
1、對於結構體裡面的成員變量的內存布局,gcc 和 VC 是相同的(如果不考慮 gcc 的優化),對於函數中緊挨著的變量,gcc 是在變量的後面(低地址)補齊,VC 是在變量的前面(高地址)補齊

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved