C++ 浅析调试,内存重叠查看
这里举个例子查看内存,
环境为:vs 2017 测试为strcpy【因为测试老api,需要在 预处理中 添加 _CRT_SECURE_NO_WARNINGS 】
测试问题:内存溢出
源码:
#include <iostream>
#include <stdlib.h>
#include <string>
#define MY_STR "hello"
#define YOUR_STR "boom"
#define NUMBERS "0123456789"
#define MAX_LENGTH 12
using namespace std;
void changed_str(char *szArry,const char *Data)
{
cout << "before copy data " << endl;
strcpy(szArry, Data);
cout << "after copy data " << endl;
}
int main()
{
char Arry[MAX_LENGTH] = { 0 };
/*
changed_str(Arry, MY_STR);
cout << Arry << endl;
memset(Arry,0,strlen(Arry));
changed_str(Arry, YOUR_STR);
cout << Arry << endl;
*/
strcpy(Arry, NUMBERS);
strcpy(Arry+3, Arry);
for (int i=0;i<sizeof(Arry);i++)
cout << Arry[i] << endl;
system("pause");
return 0;
}
现在是给足长度的数组,然后进行拷贝,成功拷贝字符串,并没有发现问题。

现对比,长度不够,然后拷贝字符串:
内存溢出如果没有踩内存是没有蹦的

接下来是查看内存重叠strcpy

为了方便做对比先列下strcpy原理【非常暴力毫无安全可言,旧版本的,现在新版本的估计已经替换了】:
甚至没有做校验assert,直接拿来测试会死循环
void strcpy( char *strDest, char *strSrc )
{
while( (*strDest++ = * strSrc++) != ‘\0’ );
}
strcpy(a+3, a); 内存重叠
开始拷贝:
a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} //注意这里a的长度是12
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
直到第六次拷贝:
a[7] = a[4] // a[4]值为 1
a[] = {0, 1, 2, 0, 1, 2, 3, 7, 8, 9}
{0, 1, 2, 0, 1, 2, 3, 7, 8, 9}
a[9] = a[6] // a[6]值为 3
a[] = {0, 1, 2, 0, 1, 2, 3, 1, 2, 3}
{0, 1, 2, 0, 1, 2, 3, 7, 8, 9}
a[10] = a[7] // a[7]值为 7
a[] = {0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 7}
{0, 1, 2, 0, 1, 2, 3, 7, 8, 9}
a[11] = a[8] // a[8]值为 2 为什么这里数组a[8]刷新了? 同步了上面
a[] = {0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 7}
{0, 1, 2, 0, 1, 2, 3, 7, 2, 9}
a[12] = a[9] // a[9] 值为 3
a[] = {0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 7, 2, 3}
{0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 7, 2, 3}
a[13] = a[10] // a[9] 值为 7
a[] = {0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 7, 2, 3, 7}
{0, 1, 2, 0, 1, 2, 3, 1, 2, 3, 7, 2, 3, 7}//这里长度应该跟上面一样的
同一个数组踩内存这里不会崩溃,也不会出现其他问题,还可以正常输出,如果是不同的变量,可能会引起程序崩溃,
所以建议使用strcpy_s安全版本拷贝,或者使用strcpy的时候自己增加外部校验判断参数合法性。
此处只做总结分享。
C++ 浅析调试,内存重叠查看的更多相关文章
- Instruments指南:如何调试内存泄露
Instruments指南:如何调试内存泄露 开篇 现在,你应该使用的ARC,而不是原来我们使用的MRC或者其他.但是我们在使用ARC的时候也会出现内存泄露的情况. 幸运的是,苹果为我们提供了Inst ...
- linux共享内存的查看与删除
在使用共享内存的程序异常退出时,由于没有释放掉共享内存,在调试时会出现错误.您可以使用shell命令来查看与释放已经分配的共享内存,下面将详细说明如何进行查看和释放分配的共享内存的方法. 预备知识 L ...
- Android学习系列(37)--App调试内存泄露之Context篇(下)
接着<Android学习系列(36)--App调试内存泄露之Context篇(上)>继续分析. 5. AsyncTask对象 我N年前去盛大面过一次试,当时面试官极力推荐我使用AsyncT ...
- 用"僵尸对象"调试内存管理问题
Cocoa提供了"僵尸对象"(Zombie Object)这个功能.启用这项调试功能之后,运行时系统会把所有已经回收的实例转化成特殊的"僵尸对象",而不会真正回 ...
- C++中两块内存重叠的string的copy方法
如果两段内存重叠,用memcpy函数可能会导致行为未定义. 而memmove函数能够避免这种问题,下面是一种实现方式: #include <iostream> using namespac ...
- 移动端页面 iPhone + Safari 页面调试 之 正确查看网络请求的姿势
如题 本文主要将 Safari + iPhone 前端开发调试 之 正确查看网络请求的 姿势 惯例 说下问题场景: 早知道safari(Mac) + iPhone 调试的方便 能解决很多日常调试问题 ...
- memmove 和 memcpy的区别以及处理内存重叠问题
区别: memcpy和memmove()都是C语言中的库函数,在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, const v ...
- [整理]内存重叠之memcpy、memmove
函数原型: void *memcpy( void *dest, const void *src, size_t count ); void *memmove( void* dest, const vo ...
- 浅析JVM内存区域及垃圾回收
一.JVM简介 JVM,全称Java Virtual Machine,即Java虚拟机.以Java作为编程语言所编写的应用程序都是运行在JVM上的.JVM是一种用于计算设备的规范,它是一个虚构出来的计 ...
随机推荐
- 前端框架和其他:1.谈谈你对http协议的认识。
1.http是一种网络数据传输协议 hype text transfer protocol-超文本传输协议 2.传输什么:超文本(html文档) 3.协议遵守方,浏览器和服务器 4.一般的传输流程是 ...
- List和Tuple的中的method对比
- 【NLP新闻-2013.06.03】New Book Where Humans Meet Machines
英语原文地址:http://nlp.hivefire.com/articles/share/39865/ 注:本人翻译NLP新闻只为学习专业英语和扩展视野,如果翻译的不好,请谅解! (我挺想看这本书的 ...
- React笔记02——React中的组件
一个网页可以被拆分成若干小部分,每个部分都可以称为组件,即组件是网页中的一部分.组件中还可以有多个组件. 上一节中的App.js就是一个组件(继承了React.Component类的类). 一个组件的 ...
- 4412 使用小度wifi
本文转载至:https://blog.csdn.net/robertsong2004/article/details/42985223 作者:刘老师,华清远见嵌入式学院讲师. FS_4412可以同链接 ...
- 【UNR #2】黎明前的巧克力 解题报告
[UNR #2]黎明前的巧克力 首先可以发现,等价于求 xor 和为 \(0\) 的集合个数,每个集合的划分方案数为 \(2^{|S|}\) ,其中 \(|S|\) 为集合的大小 然后可以得到一个朴素 ...
- 20 October in ss
Contest A: sum 快速读. B: 鬼谷子的钱袋(coin) 贪心. 按照类似二进制的方式准备钱袋:1, 2, 4, 8, ... 以此装入的钱袋数目记为 \(N\). 如果最后剩余不足以凑 ...
- git 小错误
(一)在本地直接修改文件,提交后出现(master|REBASE 1/2).由于文件冲突所以导致各种报错. 在git pull --rebase origin master后 error: Pulli ...
- centos7不能远程登陆的方案
网上找了很多,就算百度经验写的都是坑,代码如下: BROWSER_ONLY=no BOOTPROTO=static DEFROUTE=yes IPV4_FAILURE_FATAL=no IPV6INI ...
- nginx配置-location
以 =开头表示精确匹配如 A 中只匹配根目录结尾的请求,后面不能带任何字符串. ^~ 开头表示uri以某个常规字符串开头,不是正则匹配 ~ 开头表示区分大小写的正则匹配; ~* 开头表示不区分大小写的 ...