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

背景

我们定义一个变量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界面开发、黑客等等....

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

  1. C语言学习(记录)【内存相关_1:内存基础】

    本学习是基于嵌入式的C语言学习记录(课程内容来源于某位老师的网络课程,为了证明不是在打广告,就不写出老师的名字了,感谢.) -------------------------------------- ...

  2. Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器

    Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...

  3. 从硬件到语言,详解C++的内存对齐(memory alignment)

    转载请保留以下声明 作者:赵宗晟 出处:https://www.cnblogs.com/zhao-zongsheng/p/9099603.html 很多写C/C++的人都知道“内存对齐”的概念以及规则 ...

  4. 从硬件到语言,详解C++的内存对齐(memory alignment)(一)

    作者:赵宗晟 出处:https://www.cnblogs.com/zhao-zongsheng/p/9099603.html 很多写C/C++的人都知道“内存对齐”的概念以及规则,但不一定对他有很深 ...

  5. Swift3.0语言教程获得一个公共的前缀

    Swift3.0语言教程获得一个公共的前缀 Swift3.0语言教程获得一个公共的前缀,当在一个程序中有多个字符串时,我们需要判断是否有两个字符串有公共的前缀时,是很困难的.在NSString中的co ...

  6. 采用 PAT工具及CSP语言,对一个问题进行自动机 建模

    pat是新加坡国立开发的工具,需要的去官网下http://www.comp.nus.edu.sg/~pat/ ,学了一天,是个不错的自动机验证工具,感觉还不错啊. 验证一个数是否为斐波那契数且为质数 ...

  7. 李洪强iOS开发之【零基础学习iOS开发】【02-C语言】02-第一个C语言程序

    前言 前面已经唠叨了这么多理论知识,从这讲开始,就要通过接触代码来学习C语言的语法.学习任何一门语言,首先要掌握的肯定是语法.学习C语言语法的目的:就是能够利用C语言编写程序,然后运行程序跟硬件(计算 ...

  8. 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧拿出来拍啊

    花10天时间用C语言做了个小站 http://tieba.yunxunmi.com/index.html 简称: 云贴吧 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧 ...

  9. 用Racket语言写了一个万花筒的程序

    用Racket语言写了一个万花筒的程序 来源:https://blog.csdn.net/chinazhangyong/article/details/79362394 https://github. ...

随机推荐

  1. i春秋公益赛之BFnote

    题目链接:https://buuoj.cn/challenges#gyctf_2020_bfnote 首先检查程序开的保护: 发现程序只开了canary和NX保护,接下来查看IDA反汇编出来的为代码, ...

  2. shell 逻辑判断

    || && 查了 Stack Overflow ||,表示或,从前往后执行,执行第一个真 &&,前者是真才会接着执行 ; 表示接着往下执行,不管前者如何 #!/bin/ ...

  3. Kafka入门(4):深入消费者

    摘要 在这一篇文章中,我将向你介绍消费者的一些参数. 这些参数影响了每次poll()请求的数据量,以及等待时间. 在这之后,我将向你介绍Kafka用来保证消费者扩展性以及可用性的设计--消费者组. 在 ...

  4. nodejs解压版安装和配置(带有搭建前端项目脚手架)

    nodejs 安装  我先前用了nvm,觉得nvm挺厉害可以随时更换nodejs版本,但是研究了下,可能自己功力不够还是什么,并不好用,中间还出现了错误:所以最后还是卸载了: 本文图文并茂的一步一步的 ...

  5. 编程体系结构(03):Java集合容器

    本文源码:GitHub·点这里 || GitEE·点这里 一.集合容器简介 集合容器是Java开发中最基础API模块,通常用来存储运行时动态创建的元素,基本特点如下: 泛型特点,存储任意类型对象: 动 ...

  6. 2020重新出发,JAVA高级,JVM种设计模式

    Java的23种设计模式全面解析 设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路.它不是语法规定,而是一套用来提高代码可复用性.可维护性.可读性.稳健 ...

  7. [剑指Offer]61-扑克牌中的顺子

    题目 "红心A,黑桃3,小王,大王,方片5",大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13.上面的5张牌就可以变成"1,2,3,4,5" ...

  8. openstack 介绍

    penstack介绍(1)   一.云计算的前世今生 所有的新事物都不是突然冒出来的,都有前世和今生.云计算也是IT技术不断发展的产物. 要理解云计算,需要对IT系统架构的发展过程有所认识. 请看下 ...

  9. 前端直传文件到aliyun OSS

    <template> <div id="container"> <div class="img-item m-1 upload-file&q ...

  10. java8的::

    public static void main(String[] args) throws Exception { // 第一种方法引用的类型是构造器引用,语法是Class::new,或者更一般的形式 ...