前往
大廳
主題

C變數的唯讀(const)和改值(pointer),補充記憶體位置的判讀

Yang | 2023-09-17 10:34:30 | 巴幣 0 | 人氣 119

參考資料

32位元程式的記憶體位置是4 bytes,16進位輸出會變成8 chars,程式碼寫成
printf("%p", pointer);
顯示上看起來沒問題

但是64位元程式記憶體8 bytes,用%p顯示時前4 bytes看起來很怪,原因不明
(甚至前4 bytes在不同平台上顯示上會有不同問題,難以解釋)

後來在網路上找到,程式碼寫成
printf("0x%016lX", (uintptr_t)pointer);
16lX代表16進位英文大寫輸出16 chars,x則是小寫輸出
16左邊的0代表顯示時向左補0
記憶體位置的顯示終於看起來正常

程式碼範例
void ChangeConst(const int& source, const int& addValue)
{
    int *ptr = (int *)&source;
    *ptr = source + addValue;
}

const int MyPID = getpid();

printf("MyPID=%d\n", MyPID);
printf("MyPID=0x%08X\n", MyPID);
printf("MyPID addr(p)=%p\n", &MyPID);
printf("MyPID addr(X)=0x%016lX\n\n", (uintptr_t)&MyPID);

ChangeConst(MyPID, 1);

const int myPIDcopy = MyPID;
ChangeConst(myPIDcopy, 1);

printf("MyPID=%d\n", MyPID);
printf("MyPID=0x%08X\n", MyPID);
printf("MyPID addr(p)=%p\n", &MyPID);
printf("MyPID addr(X)=0x%016lX\n\n", (uintptr_t)&MyPID);

printf("myPIDcopy=%d\n", myPIDcopy);
printf("myPIDcopy=0x%08X\n", myPIDcopy);
printf("myPIDcopy addr(p)=%p\n", &myPIDcopy);
printf("myPIDcopy addr(X)=0x%016lX\n\n", (uintptr_t)&myPIDcopy);

輸出
MyPID=25035171
MyPID=0x017E01A3
MyPID addr(p)=12000aa25
MyPID addr(X)=0x000000012000AA25

MyPID=25035172
MyPID=0x017E01A4
MyPID addr(p)=12000aa25
MyPID addr(X)=0x000000012000AA25

myPIDcopy=25035173
myPIDcopy=0x017E01A5
myPIDcopy addr(p)=fffffffffffe390
myPIDcopy addr(X)=0x0FFFFFFFFFFFE390

以上能看到%p顯示記憶體位置時前4 bytes異常,%016lX搭配uintptr_t顯示正常

以上範例也確定唯讀的const int MyPID值還是可以被異動(記憶體位置不變),但只要先複製一次資料,
const int myPIDcopy = MyPID; //myPIDcopy和MyPID記憶體位置不同
就能避免MyPID被異動

當懷疑ChangeConst(或其他)函式有問題時,
小心使用函式的其中一種方式就是參數輸入前都要先複製,
MyPID -> myPIDcopy
避免原始資料被異動
送禮物贊助創作者 !
0
留言

創作回應

更多創作