与内存有关的那些事儿(数组分配空间不够,导致缓冲区溢出,从而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
与内存有关的那些事儿(数组分配空间不够,导致缓冲区溢出,从而strcpy会出现异常)的更多相关文章
- C语言malloc函数为一维,二维,三维数组分配空间
c语言允许建立内存动态分配区域,以存放一些临时用的数据,这些数据不必在程序的声明部分定义,也不必等到函数结束时才释放,而是需要时随时开辟,不需要时随时释放,这些数据存储在堆区.可以根据需要,向系统申请 ...
- Java数组分配内存空间
分配内存空间 数组名=new 数据类型[数组长度]: new关键字用来实现为数组或对象分配内存 数组具有固定的长度.获取数组的长度: 数组名.length 定义数组+分配内存空间 数据类型[]数组名= ...
- 06-01 Java 二维数组格式、二维数组内存图解、二维数组操作
二维数组格式1 /* 二维数组:就是元素为一维数组的一个数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的 ...
- Java8内存模型—永久代(PermGen)和元空间(Metaspace)(转)
Java8内存模型—永久代(PermGen)和元空间(Metaspace) 查看原文点击传送门:http://www.cnblogs.com/paddix/p/5309550.html 提示:本文做了 ...
- Java8内存模型—永久代(PermGen)和元空间(Metaspace)
一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 1.虚拟机栈:每个线程有一个私有的栈,随着线程的创建而创建.栈里面存着的是一种叫“栈 ...
- (转)Java8内存模型—永久代(PermGen)和元空间(Metaspace)
背景:介绍java8中永久代到元空间的转变. Java8内存模型—永久代(PermGen)和元空间(Metaspace) 一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法 ...
- 转:Java8内存模型—永久代(PermGen)和元空间(Metaspace)
一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 1.虚拟机栈:每个线程有一个私有的栈,随着线程的创建而创建.栈里面存着的是一种叫“栈 ...
- Java8内存结构—永久代(PermGen)和元空间(Metaspace)
本文转载 作者:liuxiaopeng 博客地址:https://www.cnblogs.com/paddix/p/5309550.html 一.JVM 内存结构 根据 JVM 规范,JVM 内存共分 ...
- 只要没有给String[]数组new 空间,那么他就只是一个引用
public class Test1 { @Test public void test(){ String[] values = {"good", "morning&qu ...
随机推荐
- SGU 106 The Equation 扩展欧几里得应用
Sol:线性不定方程+不等式求解 证明的去搜下别人的证明就好了...数学题. #include <algorithm> #include <cstdio> #include & ...
- eclipse的SVN插件的配置
http://www.cnblogs.com/kekec/archive/2010/08/09/1795581.html
- 一张图说清Asp.NET MVC中的 RenderPage、RenderBody、RenderSection
- C#由变量捕获引起对闭包
C#由变量捕获引起对闭包的思考 前言 偶尔翻翻书籍看看原理性的东西确实有点枯燥,之前有看到园中有位园友说到3-6年工作经验的人应该了解的.NET知识,其中就有一点是关于C#中的闭包,其实早之前在看 ...
- WCF技术剖析之十七:消息(Message)详解(上篇)
原文:WCF技术剖析之十七:消息(Message)详解(上篇) [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话)]]消息交换 ...
- 互联网组织的未来:剖析GitHub员工的任性之源(转)
如果有这么家任性的公司,没有所谓“经理人”这一层,人都在做自己喜欢的事情,并且创造价值,而其他的事情,就顺其自然让他发生.这里能节省多少官僚主义带来的浪费?这样的公司得跑得有多快?得有多少无谓的冲突消 ...
- JS Call()与Apply()
JS Call()与Apply() ECMAScript规范给所有函数都定义了Call()与apply()两个方法,call与apply的第一个参数都是需要调用的函数对象,在函数体内这个参数就是thi ...
- 来推荐个免费的PPT演示工具--ZohoShowTime
事实上这个不算新产品了,这次是做了一些大的改进.上次在Zoho的全球用户大会上,全程演讲都是用的这个工具.Zoho这点非常好啊.自己的产品自己带头用.个人认为它最大的用处就是.离得远的观众能够在自己的 ...
- cocos2d-x 新建项目 Cannot open include file: ‘cocos2d.h’
新建cocos2d-x 项目分这么几步. 1. 下载最新的cocos2d-x 2. 安装 vs2010 3. 解压cocos2d-x 压缩包,并双击"install-templates-ms ...
- Java面试题精选(一)基础概念和面向对象
-- 基础概念和面向对象 -- 全程将为大家剖析几大部分内容,由于学习经验有限,望大家谅解并接受宝贵的意见: 基础概念部分 ★★ : 常出现的高频率单词的区别理解(异常. ...