C语言的污垢,一个能污染内存的神秘操作!神级坑位再现~

246 阅读3分钟

本文目的是为了更好的理解指针和内存管理

背景

我们定义一个变量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;

}

![](https://upload-images.jianshu.io/upload_images/24175598-2930bd6843dc13b0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

验证

我们通过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

![](https://upload-images.jianshu.io/upload_images/24175598-cccdd315acd35993.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

结论: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++编程学习基地【点击进入】!**

![](https://upload-images.jianshu.io/upload_images/24175598-eb2801bb4cbb7d80.gif?imageMogr2/auto-orient/strip)

一个活跃、高逼格、高层次的编程学习殿堂;编程入门只是顺带,思维的提高才有价值!

**涉及:**编程入门、游戏编程、网络编程、Windows编程、Linux编程、Qt界面开发、黑客等等....