• 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++) != ‘’ );   

     }

    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的时候自己增加外部校验判断参数合法性。

    此处只做总结分享。

  • 相关阅读:
    漫谈程序员系列:咦,你也在混日子啊
    JVM加载class文件的原理机制
    maven编译的时候排除junit测试类
    mysql之——存储过程 + 游标 + 事务
    JSP页面之${fn:}内置函数
    生成24位字符串ID__IdGenerator.java
    oracle创建用户,表空间,虚拟路径,导入dbf
    eclipse手动修改默认工作空间
    资源
    http协议发送header+body+json及接收解析
  • 原文地址:https://www.cnblogs.com/liuruoqian/p/11529391.html
Copyright © 2020-2023  润新知