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界面开发、黑客等等....
C语言的污垢,一个能污染内存的神秘操作!神级坑位再现~的更多相关文章
- C语言学习(记录)【内存相关_1:内存基础】
本学习是基于嵌入式的C语言学习记录(课程内容来源于某位老师的网络课程,为了证明不是在打广告,就不写出老师的名字了,感谢.) -------------------------------------- ...
- Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器
Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...
- 从硬件到语言,详解C++的内存对齐(memory alignment)
转载请保留以下声明 作者:赵宗晟 出处:https://www.cnblogs.com/zhao-zongsheng/p/9099603.html 很多写C/C++的人都知道“内存对齐”的概念以及规则 ...
- 从硬件到语言,详解C++的内存对齐(memory alignment)(一)
作者:赵宗晟 出处:https://www.cnblogs.com/zhao-zongsheng/p/9099603.html 很多写C/C++的人都知道“内存对齐”的概念以及规则,但不一定对他有很深 ...
- Swift3.0语言教程获得一个公共的前缀
Swift3.0语言教程获得一个公共的前缀 Swift3.0语言教程获得一个公共的前缀,当在一个程序中有多个字符串时,我们需要判断是否有两个字符串有公共的前缀时,是很困难的.在NSString中的co ...
- 采用 PAT工具及CSP语言,对一个问题进行自动机 建模
pat是新加坡国立开发的工具,需要的去官网下http://www.comp.nus.edu.sg/~pat/ ,学了一天,是个不错的自动机验证工具,感觉还不错啊. 验证一个数是否为斐波那契数且为质数 ...
- 李洪强iOS开发之【零基础学习iOS开发】【02-C语言】02-第一个C语言程序
前言 前面已经唠叨了这么多理论知识,从这讲开始,就要通过接触代码来学习C语言的语法.学习任何一门语言,首先要掌握的肯定是语法.学习C语言语法的目的:就是能够利用C语言编写程序,然后运行程序跟硬件(计算 ...
- 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧拿出来拍啊
花10天时间用C语言做了个小站 http://tieba.yunxunmi.com/index.html 简称: 云贴吧 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧 ...
- 用Racket语言写了一个万花筒的程序
用Racket语言写了一个万花筒的程序 来源:https://blog.csdn.net/chinazhangyong/article/details/79362394 https://github. ...
随机推荐
- Python日志功能与处理逻辑
前言 在应用程序执行过程中,我们希望通过规范格式输出程序执行的详细信息,这时我们需要用到日志功能.在Python语言中,有个內建模块logging能够很好的实现日志功能.整体来说,logging配置可 ...
- Python实现加密的ZIP文件解压(密码已知)
博主在上篇博文介绍了<Python实现加密的RAR文件解压(密码已知)>后,又尝试了ZIP文件的解压方法,下面开始分享. 当ZIP文件的压缩密码已知时,可以通过调用zipfile库进行解压 ...
- linux6.4内核由2.6升级成3.6
安装CentOS 6.4之后,内核默认是2.6.32.由于docker需要3.0以上的内核,所以需要对内核进行升级. 1. 安装必要组件# yum -y install ncurses-devel # ...
- oracle之三手工不完全恢复
手工不完全恢复 4.1 不完全恢复的特点: 1)让整个database 回到过去某个时间点,不能避免数据丢失. 2)想跳过坏日志而继续恢复所有其他工作是不可能的,前滚没有这个功能(考点). 3)必须以 ...
- Spring基于XML的IOC环境搭建及入门
一.使用Maven构建Java项目 * 项目目录结构 1. 在sun.service包下创建UserDao接口和接口实现类: UserDao接口: package sun.service; /** * ...
- tomcat源码之概述
tomcat架构及常用的组件如下: Server Server代表了tomcat服务器,Tomcat启动时即会启动一个server实例,它监听在8005端口以接收shutdown命令,使用 telne ...
- 修改python包pip下载国内源
第一种方式- pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ 附国内常用镜像源:阿里云:https:// ...
- 《Java从入门到失业》第四章:类和对象(4.5):包
4.5包 前面我们已经听过包(package)这个概念了,比如String类在java.lang包下,Arrays类在java.util包下.那么为什么要引入包的概念呢?我们思考一个问题:java类库 ...
- 《SpringCloudDubbo开发日记》(一)Nacos连官方文档都没写好
背景 现在的微服务框架一般分dubbo和springcloud两套服务治理体系,dubbo是基于zookeeper为注册中心,springcloud是基于eureka作为注册中心. 但是现在eurek ...
- Python练习题 007:兔子生兔子
[Python练习题 007] 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? ----------------- ...