1. 程式人生 > 實用技巧 >C語言的汙垢,一個能汙染記憶體的神祕操作!神級坑位再現~

C語言的汙垢,一個能汙染記憶體的神祕操作!神級坑位再現~

本文目的是為了更好的理解指標和記憶體管理

背景

我們定義一個變數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介面開發、黑客等等....