我正在將地址為 0x7ffc684486ef 的字符變數的地址型別轉換為整數指標。地址 0x7ffc684486ef 處的值是 16,當我使用整數指標取消參考時,它將讀取從地址 0x7ffc684486ef 開始的 4 個位元組,但它回傳值 0,這是怎么回事。我的理解有誤嗎?
int main()
{
char var;
int *ptr;
ptr = (int *)&var;
printf("%p %p\n", &var, ptr);
*ptr = 16;
printf("%d %d\n", var, *ptr);
return 0;
}
開/關
0x7ffc684486ef 0x7ffc684486ef
16 0
- 為什么下面的代碼不列印任何東西。
#include <stdio.h>
#define ADDRESS 0x7ffc684486ef
typedef struct Point {
int x;
int y;
}Point;
int main()
{
Point *var = (Point *)(ADDRESS);
var->x = 2;
var->y = 5;
printf("Location: %p\n", var);
printf("Values: %d %d\n", var->x, var->y);
}
開/關:
NIL
uj5u.com熱心網友回復:
C 允許非常不安全的指標轉換,例如ptr = (int *)&var;無需抗議。因此,即使在更改指標型別后,您也可能獲得相同的地址。
但是,當您取消參考時,*ptr = 16;您會呼叫大量未定義的行為錯誤:越界訪問、可能未對齊的訪問、嚴格的別名違規、訪問您無權訪問的記憶體,等等。不要這樣做,這段代碼非常糟糕,而且不知道結果會是什么。什么是未定義行為,它是如何作業的?
第二個例子更糟糕:
- 你怎么知道在那個地址有你可以訪問的記憶體?
- 這是一個未對齊的地址,因此您無法在大多數計算機上將其作為結構訪問
- 必須
volatile限定對編譯器未知的記憶體區域(例如硬體暫存器)的訪問。
所以看起來你在 la-la-land 的某個地方做了一個未對齊的地址,這也是非常未定義的行為。對您可能遇到的任何行為進行推理是沒有意義的。任何形式的行為都可能發生。
uj5u.com熱心網友回復:
只是為了澄清與 *p = 16 相關的概念......看這段代碼:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int numa = -1, num, numb = -1;
int *p = (int *)#
*p = 16;
printf("\n%d %d %d %d", *p, numa, num, numb);
}
運行時會輸出:
16 -1 16 -1
現在嘗試在宣告 'num' 的行上將資料型別更改為 char:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char numa = -1, num, numb = -1;
int *p = (int *)#
*p = 16;
printf("\n%d %d %d %d", *p, numa, num, numb);
}
您將收到“分段錯誤”。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/380463.html
標籤:C
