如何讓指標8位元組讀取?下乙個位址偏移到底是多少?

2021-10-09 01:14:23 字數 3013 閱讀 2021

我覺得最好的答案是:自己用編譯器測試。總體來說和作業系統位數有關,可以用下面的兩句話概括。

乙個指標在32位作業系統上,佔4個位元組。

乙個指標在64位作業系統上,佔8個位元組。

我用vs2019測試,x86都是4位元組,x64都是8位元組。

std:

:cout <<

sizeof

(int*)

<<

" "<<

sizeof

(void*)

<<

" "<<

sizeof

(double*)

<<

" "<<

sizeof

(char*)

<< std:

:endl;

std:

:cout <<

sizeof

(long*)

<<

" "<<

sizeof

(long

long*)

<<

" "<<

sizeof

(short*)

<<

" "<<

sizeof

(float*)

<< std:

:endl;

;

這裡是8位元組讀取位址,比4位元組讀取會有不同

為了讓程式有實用價值,這裡用void*來演示,因為:本意這用來做dll,供外部呼叫,所有必須用void*轉換內部類的指標。

首先,我把void*認為成handle。

typedef

void

* handle;

之後,

如何返回內部建立的陣列首位址,一種簡單的做法是:傳入handle型別的位址,之後解引用即可。由於內部要解引用,切不可傳入空指標,即handle。多說一句,你想想handle是什麼,是空指標,解引用直接異常。然而這裡傳入的是空指標的位址哈。

void

create

(handle* pfd_handle)

;*pfd_handle = handle;

printf

("%p, %p, %p\n"

,&handle[0]

,&handle[1]

,&handle[2]

);}

這裡輸出的是陣列元素的位址,其內容我沒有填哦!!!

注意:下面的**用x64,x86都是沒問題。

len會根據具體平台得到4或者8

char* p是最有意思的,將pfd_handle轉化成char* ,我們所謂的指標偏移+1?難道都是1嗎?當然不是。

如果是int*型別的指標,那麼+1,表示下乙個int*位址,當然在x64跳躍8位元組,在x86跳躍4位元組。

同理double*,float*。+1會自動跳對應的位元組。這是自動的。

但是在這裡,這樣是行不通的。下面的方式編譯器直接報錯,因為pfd_handle是handle型別,e0852 表示式必須是指向完整物件型別的指標,既然把handle認定成void*,那麼只能把handle認為成簡單的型別,比如int,double等型別,換句話說,編譯器只有看到*或,等才會給你解引用權力,如果你是個int p, *p編譯器直接報錯。或許p裡面裝著乙個位址(我對乙個位址解引用,沒問題呀?但是你繞不過編譯器,編譯器只認為p是個數,沒有權利解引用)。然而如果是int *p;編譯器認*p,p+1都是合法。

下面就很好理解了,這麼寫的主要原因,是因為程式設計師你認為pfd_handle是空指標,對它加一就是下乙個位址,但是編譯器只把它當作乙個簡單的型別。

void

process

(handle pfd_handle)

為此,必須換個方式,我們知道x64下指標大小是8位元組,這樣就先用len裝著,先把pfd_handle轉成char*型別,我們知道char只佔1個位元組,那麼如何偏移8個位元組呢?直接加上len即可。如下

void

process

(handle pfd_handle)

這個問題很簡單,問題是你是否把指標進行了強制準換這一點很重要。

然而對於轉換後的呢?就拿上面的void*來說,先把它轉成char*,而char型別只佔乙個位元組的記憶體,那麼就應該+8才是下乙個void*,同理我把它轉成int*,int型別佔4位元組記憶體,達到8,只需要+2即可。

總之,對於強制轉換的位址,要依賴轉換型別而定,一般就轉換成char*,因為char佔乙個位元組記憶體,方便計數。

釋放陣列內容就不說了。

handle handle_t =0;

create

(&handle_t)

;//務必傳入位址

printf

("%p\n"

, handle_t)

;process

(handle_t)

; delete[

] handle_t;

// 輸出,正確讀出,當然這只是陣列三個位址,不涉及內容哈

00000256a3e5fd30,

00000256a3e5fd38,

00000256a3e5fd40

00000256a3e5fd30

00000256a3e5fd30,

00000256a3e5fd38,

00000256a3e5fd40

主要的內容

按任意位元組讀取記憶體?

指標被強制轉換後,該怎麼操作?

void* 可以隔離內外,傳遞乙個handle_t完成所有操作。

位元組對齊 8位元組對齊

參考博文 參考1 參考2 參考3 在記憶體管理中經常使用位元組對齊來管理分配的記憶體。1 原理 2 演算法 2.1unsigned intcalc align unsigned int n,unsigned align 2.2 更好的演算法 unsigned intcalc align unsign...

測試8位元組對齊

對十六進製制和按位操作,總是糊塗,所以實際測試下 我的理解,不一定全部正確 32位的系統上,都以32位系統為例 乙個int型是4個位元組,所以0x3是 0x0003,四個位元組,其中3代表乙個位元組 8個二進位制位 00000011,0就是00000000了。乙個指標也是4個位元組,這個程式裡頭列印...

8位位元組對齊演算法

參考文章 8bit對齊演算法 void testalign 1byte 1位元組對齊 unsigned int align8bit unsigned int n 2byte 2位元組對齊 unsigned int align16bit unsigned int n 4byte 4位元組對齊 unsi...