記憶體地址、大端小端問題
阿新 • • 發佈:2018-11-15
記憶體地址
一個記憶體地址可儲存 8 bit = 1 byte(位元組)
32位作業系統可定址空間為 2^32 (Byte) = 2^10 * 2^10 * 2^10 *4 = 4 GB
資料所佔記憶體大小
C宣告 | 位元組數 | 位元組數 |
---|---|---|
有符號 | 32位 | 64位 |
char | 1 | 1 |
short | 2 | 2 |
int | 4 | 4 |
long | 4 | 8 |
char* | 4 | 8 |
float | 4 | 4 |
double | 8 | 8 |
大端小端
32bit寬的16進位制 0x12345678 在記憶體中的存放方式:
大端: 高位元組儲存在低地址,低位元組儲存在高地址
記憶體地址 | 0x4000 | 0x4001 | 0x4002 | 0x4003 |
---|---|---|---|---|
存放內容 | 0x12 | 0x34 | 0x56 | 0x78 |
小端: 低位元組儲存在低地址,高位元組儲存在高地址
記憶體地址 | 0x4000 | 0x4001 | 0x4002 | 0x4003 |
---|---|---|---|---|
存放內容 | 0x78 | 0x56 | 0x34 | 0x12 |
union 共用體
任何時刻共用體中只存放了一個被選中的成員
所有成員都從低地址開始存放
結構體和共用體的區別在於:
結構體的各個成員會佔用不同的記憶體,互相之間沒有影響;而共用體的所有成員佔用同一段記憶體,修改一個成員會影響其餘所有成員。
結構體佔用的記憶體大於等於所有成員佔用的記憶體的總和(成員之間可能會存在縫隙),共用體佔用的記憶體等於最長的成員佔用的記憶體。共用體使用了記憶體覆蓋技術,同一時刻只能儲存一個成員的值,如果對新的成員賦值,就會把原來成員的值覆蓋掉。
判斷大端小端
#define BIG_ENDIAN 0
#define LITTLE_ENDIAN 1
int TestByteOrder(){
short int word = 0x0001;
char* byte = (char*) &word;//自地址總是指向低地址,&word 即為字地址
return (byte[0] ? LITTLE_ENDIAN : BIG_ENDIAN );
}
#include <iostream>
using namespace std;
union TEST{
short a;
char b[sizeof(short)];
};
int maint(){
TEST test;
test.a = 0x0102;
if(test.b[0] == 0x01 && test.b[1] == 0x02){
cout << "big endian."<< endl;
}
else if(test.b[0] == 0x02 && test.b[1] == 0x01){
cout << "little endian" << endl;
}
else{
cout << "unknown" << endl;
}
return 0;
}
棧地址生產方式:從高地址到低地址
- 先分配的變數存在高地址,後分配的存在低地址
- 棧空間由編譯器開闢和釋放,主要存放區域性變數和函式引數