与内存有关的那些事儿(数组分配空间不够,导致缓冲区溢出,从而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 ...
随机推荐
- html+css实现图片的层布局
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- haproxy 配置日志
jrhppt01:/root# vim /etc/haproxy/haproxy.cfg # this config needs haproxy-1.1.28 or haproxy-1.2.1 glo ...
- ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables opt
mysql跳过权限: mysqld -nt --skip-grant-tables opt 登录:mysql -uroot -p 修改root密码 set password for 'root'@'l ...
- Swift - 禁用UIWebView和WKWebView的下拉拖动效果
使用UIWebView或WKWebView加载网页时,如果页面处于最顶端时,用户用手指往下拖动,会露出灰色空背景.同样页面在最底部的时候,继续向上拖动,下方也会露出空背景. 要禁止这个拖动效果,可进行 ...
- UML02-用例图
1.泛化表示一般和特殊的关系.用例之间存在泛化关系,参与者之间存在泛化关系,参与者和用例之间存在泛化关系. 2.画出用例图. 系统允许管理员通过磁盘加载存货数据来运行存货清单报告: 管理员通过从磁盘加 ...
- hdu 3874 Necklace(线段树)
这道题目和我之前做过的一道3xian大牛出的题目很像,不过总的来说还是要简单一点儿. 计算区间内的值的时候如果两个值相等,只能计算其中一个. 这道题需要将所有的问题输入之后再计算,首先,对所有问题的右 ...
- SharePoint2010 部署步骤“激活功能”中出现错误:无法启动计算机“PCName”上的服务SPUserCodeV4
在SharePoint2010开发中,选择部署类型为“部署为沙盒解决方案”,在部署代码是出现如下错误提示: 部署步骤“激活功能”中出现错误:无法启动计算机“PCName”上的服务SPUserCodeV ...
- 重操JS旧业第五弹:函数
函数在任何编程语言中起着非常重要的位置,因为他是功能的最小单元,在js中函数是一种类型 Function 1 申明与定义 显示声明:function cc(){};函数名其实是函数的一个指针,函数名某 ...
- 中国还是和AMD走到一起了 但美国会高兴吗(网易科技 卢鑫)
文/ 网易科技 卢鑫 去年的这个时候,小编写下了一篇<易评:还给AMD一个公正!>——此文由AMD惨不忍睹的第一季度财报展开,谈到了该公司将全部资源押宝2016的现实.如今,2016第一季 ...
- Gitolite v3安装配置指南
使用gitolite对git仓储进行权限配置 gitolite在近期做了很多代码改动,升级到了v3版本,而我使用的是v3.5.2.在<Git权威指南>中所提及的是v2版本,有很多东西已经不 ...