本文目的是為了更好的理解指標和記憶體管理
背景
我們定義一個變數A,修改另外一個一個變數B,導致A的值被修改,我們稱它為記憶體污染,
案例
如下程式,正常的預期輸出應該是:97 98 256 ,但正確的結果卻是1 0 256 ,意不意外,驚不驚喜
這時候主要問題發生在int *ptr = (int *)&b; 這里,對&b 強型別轉換,污染了a 的記憶體
a 的地址比b 地址大(堆從低到高, 堆疊從高到低分配地址 )
————————————
#include <stdio.h> int main(void) { char a = 'a', b = 'b'; int *ptr = (int *)&b; *ptr = 256; printf("%d,%d,%d \n", a, b, *ptr); // 1 0 256 return 0; }

驗證
我們通過gdb除錯,列印出各個變數的地址
————————————
$ gdb a.out (gdb) b 7 Breakpoint 1 at 0x100000f47: file test.c, line 7. (gdb) b 11 Breakpoint 2 at 0x100000f77: file test.c, line 11. Thread 2 hit Breakpoint 1, main () at test.c:7 7 int *ptr = (int *)&b; (gdb) x/1tb &a 0x7ffeefbff55b: 01100001 (gdb) x/1tb &b 0x7ffeefbff55a: 01100010 (gdb) n 8 *ptr = 256; (gdb) n 10 printf("%d,%d,%d \n", a, b, *ptr); // 1 0 256 (gdb) n 1,0,256 Thread 2 hit Breakpoint 2, main () at test.c:11 11 return 0; (gdb) x/1tb &a 0x7ffeefbff55b: 00000001 (gdb) x/1tb &b 0x7ffeefbff55a: 00000000 (gdb) x/4tb ptr 0x7ffeefbff55a: 00000000 00000001 00000000 00000000
————————————
我們在*ptr = 256; 這里打了斷點,然后分別看執行前后a ,b 的變化
我們先在斷點前,使用gdb命令x/1tb &a 查看記憶體
? a 的地址0x7ffeefbff55b 值為十進制97
? b 的地址0x7ffeefbff55a 值為十進制98

結論:a 的地址比b 的地址高
(gdb) x/1tb &a
0x7ffeefbff55b: 01100001
(gdb) x/1tb &b
0x7ffeefbff55a: 01100010
————————————
然后我們執行*ptr = 256; 這句后,再次查看:
(gdb) x/1tb &a
0x7ffeefbff55b: 00000001
(gdb) x/1tb &b
0x7ffeefbff55a: 00000000
(gdb) x/4tb ptr
0x7ffeefbff55a: 00000000 00000001 00000000 00000000
————————————
ptr賦值245后,記憶體中值為:00000000 00000001 00000000 00000000
直接污染了a 的記憶體,把a 值修改為了00000001 因為ptr為int* 型別,占用4個位元組,a 的地址比ptr 高1,屬于4個位元組之內,所以被污染了,
是不是很神奇呢,下次遇到這種坑小伙伴一定要注意哦!
————————————
看到這里你是不是對C語言又有了一點新的認知呢~
如果你喜歡這篇文章的話,動動小指,點個贊再走~
如果你想學編程,小編推薦一個C語言/C++編程學習基地【點擊進入】!

一個活躍、高逼格、高層次的編程學習殿堂;編程入門只是順帶,思維的提高才有價值!
涉及:編程入門、游戲編程、網路編程、Windows編程、Linux編程、Qt界面開發、黑客等等....
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/169223.html
標籤:C
下一篇:【硬核】Dubbo常見面試題
