#include <stdio.h>
int main(void)
{
char *p = NULL;
char *tmp = "12345678";
p = (char *)(tmp + 4); // tmp 指向 '1',tmp+4 指向 '5'
// p[-1] = ? p[-5] = ?
return 0;
}
tmp 位址設為 base,內容 '1','2','3','4','5','6','7','8','\0'。p = base + 4 → 指向 '5'(索引 4)。p[-1] 等價 *(p - 1) = *(base + 3) = '4'。p[-5] 等價 *(p - 5) = *(base - 1) → 未定義行為(越界存取字串常量前方記憶體)。答案:
p[-1] == '4';p[-5]觸發 UB,可能崩潰或讀到垃圾值。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *data = "12345678";
short *tmp = NULL;
char p[6] = {0};
tmp = (short *)&p[2]; // tmp 指向 p[2], p[3] (2 bytes)
*tmp = atoi(&data[4]); // data[4]='5',atoi("5678")=5678 = 0x162E
// p[0]..p[5] = ?
return 0;
}
p 初始全 0:[0,0,0,0,0,0]。tmp 指向 &p[2],寫入 short 值 5678 (0x162E)。p[2] = 低位元組 0x2E (46) → ASCII '.'p[3] = 高位元組 0x16 (22) → 控制字元p[2]=0x16, p[3]=0x2E。p[0], p[1], p[4], p[5] 保持 0。答案(小端序):
p = {0, 0, 46, 22, 0, 0}(以數值顯示)。
int *p = (int *)0x1234;
printf("p = %p, *p = %d\n", p, *p);
p 值為 0x1234,列印無問題。*p 嘗試讀取實體/虛擬位址 0x1234 的 4 位元組。SIGSEGV (Segmentation fault),程式終止。答案:程式崩潰(Segmentation fault),無法正常輸出。
p[i] ≡ *(p+i),負索引合法前提是結果位址在同一合法物件範圍內。short* 存取 char[] 違反 Strict Aliasing Rule,行為未定義(雖多數編譯器在低優化下按預期工作)。mmap、ioremap 等機制映射。union 或 memcpy 避免 Strict Aliasing 違規。NULL、對齊、映射範圍)。