zoukankan      html  css  js  c++  java
  • 与内存有关的那些事儿(数组分配空间不够,导致缓冲区溢出,从而strcpy会出现异常)

    这日,我写下如下代码:
    #include <iostream>
    int main(void)
    {
    char *p = new char[5];
    char *t = new char[5];
    strcpy(t, "Hello");
    strcpy(p, t);
    std::cout<<p<<std::endl;
    delete [] p;
    delete [] t;
    system("pause");
    return 0;
    }
    看了看,基本没问题,心想万事大吉,编译一下,可问题却出来了:
    warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
    warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
    warning C6211: 由于出现异常,正在泄漏内存“p”。应考虑使用局部 catch 块清理内存: Lines: 5, 6
    warning C6386: 缓冲区溢出: 访问“参数 1”时,“5*1”个字节可写,但可能写入了“6”个字节: Lines: 5, 6, 8
    出现4个警告,仔细看看,前2个属于同一个问题,第3个问题包含2个问题,但也属于同一类,第4个问题仔细看看,也是和第一个问题一样,是strcpy的问题;
    我纳闷,这个怎么会出现问题?看看它的提示,出现缓冲区溢出,再翻翻MSDN,上面这样写着:
    The strcpy_s function copies the contents in the address of strSource, including the terminating null character, to the location specified by strDestination. The destination string must be large enough to hold the source string, including the terminating null character. The behavior of strcpy_s is undefined if the source and destination strings overlap.
    If strDestination or strSource is a null pointer, or if the destination string is too small, the invalid parameter handler is invoked as described in Parameter Validation. If execution is allowed to continue, these functions return EINVAL and set errno to EINVAL.Upon successful execution, the destination string will always be null terminated.
    大体瞄了几眼,大体意思是说strcpy_s会尽显缓冲区溢出检测,如果有问题,则抛出一个异常,而strcpy则可能不会抛出异常但会导致程序错误,也有可能由于非法访问而抛出异常。
    第4个警告已经说明程序存在缓冲区溢出,所以strcpy会出现异常。
    再来看看第3个问题,警告说
    char *p = new char[5];
    char *t = new char[5];
    存在内存泄露,再看看MSDN,上面写道:
    警告 C6211:由于出现异常,正在泄漏内存 <pointer>。应考虑使用局部 catch 块清理内存,此警告意味着在引发异常时未释放已分配的内存。位于路径末尾的语句可能会引发异常。
    也就是说,编译器检测到程序会泄露内存,所以建议使用try...catch来清理内存。
    问题终于搞明白了,于是开始动手,代码改为如下:
    #include <iostream>
    int main(void)
    {
    char *p = NULL;
    char *t = NULL;
    try
    {
    p = new char[6];
    t = new char[6];
    strcpy_s(t, 6, "Hello");
    strcpy_s(p, 6, t);
    std::cout<<p<<std::endl;
    delete [] p;
    delete [] t;
    }
    catch(std::bad_alloc &bad)
    {
    std::cout<<bad.what()<<std::endl;
    if (NULL != p)
    {
    delete [] p;
    }
    if (NULL != t)
    {
    delete [] t;
    }
    }
    system("pause");
    return 0;
    }
    编译一下,OK,通过,运行,结果正确,问题解决。

    http://blog.csdn.net/blpluto/article/details/4515748

  • 相关阅读:
    深入理解JavaScript系列
    Knockout应用开发指南(完整版) 目录索引
    js原生设计模式——8单例模式之简约版属性样式方法库
    彻底理解JavaScript原型
    Javascript模块化编程(一):模块的写法
    使用Grunt构建自动化开发环境
    js原生之一个面向对象的应用
    js原生之函数
    angular源码分析:angular中的依赖注入式如何实现的
    js原生之scrollTop、offsetHeight和offsetTop等属性用法详解
  • 原文地址:https://www.cnblogs.com/findumars/p/5290188.html
Copyright © 2011-2022 走看看