1. 程式人生 > >記憶體地址、大端小端問題

記憶體地址、大端小端問題

記憶體地址

一個記憶體地址可儲存 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;
}

棧地址生產方式:從高地址到低地址

  • 先分配的變數存在高地址,後分配的存在低地址
  • 棧空間由編譯器開闢和釋放,主要存放區域性變數和函式引數