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

背景

我们定义一个变量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. Python日志功能与处理逻辑

    前言 在应用程序执行过程中,我们希望通过规范格式输出程序执行的详细信息,这时我们需要用到日志功能.在Python语言中,有个內建模块logging能够很好的实现日志功能.整体来说,logging配置可 ...

  2. Python实现加密的ZIP文件解压(密码已知)

    博主在上篇博文介绍了<Python实现加密的RAR文件解压(密码已知)>后,又尝试了ZIP文件的解压方法,下面开始分享. 当ZIP文件的压缩密码已知时,可以通过调用zipfile库进行解压 ...

  3. linux6.4内核由2.6升级成3.6

    安装CentOS 6.4之后,内核默认是2.6.32.由于docker需要3.0以上的内核,所以需要对内核进行升级. 1. 安装必要组件# yum -y install ncurses-devel # ...

  4. oracle之三手工不完全恢复

    手工不完全恢复 4.1 不完全恢复的特点: 1)让整个database 回到过去某个时间点,不能避免数据丢失. 2)想跳过坏日志而继续恢复所有其他工作是不可能的,前滚没有这个功能(考点). 3)必须以 ...

  5. Spring基于XML的IOC环境搭建及入门

    一.使用Maven构建Java项目 * 项目目录结构 1. 在sun.service包下创建UserDao接口和接口实现类: UserDao接口: package sun.service; /** * ...

  6. tomcat源码之概述

    tomcat架构及常用的组件如下: Server Server代表了tomcat服务器,Tomcat启动时即会启动一个server实例,它监听在8005端口以接收shutdown命令,使用 telne ...

  7. 修改python包pip下载国内源

    第一种方式- pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ 附国内常用镜像源:阿里云:https:// ...

  8. 《Java从入门到失业》第四章:类和对象(4.5):包

    4.5包 前面我们已经听过包(package)这个概念了,比如String类在java.lang包下,Arrays类在java.util包下.那么为什么要引入包的概念呢?我们思考一个问题:java类库 ...

  9. 《SpringCloudDubbo开发日记》(一)Nacos连官方文档都没写好

    背景 现在的微服务框架一般分dubbo和springcloud两套服务治理体系,dubbo是基于zookeeper为注册中心,springcloud是基于eureka作为注册中心. 但是现在eurek ...

  10. Python练习题 007:兔子生兔子

    [Python练习题 007] 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? ----------------- ...