与内存有关的那些事儿(数组分配空间不够,导致缓冲区溢出,从而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 ...
随机推荐
- Cocos2D-X扫盲之坐标系、锚点
一.引言 在Cocos2D-X的开发过程中,经常会碰到设置精灵位置的问题.而设置位置的过程,涉及到两个问题:第一是坐标系,包括原点的位置.X/Y坐标轴的方向灯:第二是基准点(Cocos2D-X中叫锚点 ...
- EXT.NET高效开发(三)——使用Chrome浏览器的开发人员工具
这篇帖子老少皆宜,不分男女,不分种族,不分职业.俗话说:“磨刀不误砍柴工”.掌握一些开发工具的使用,对自己帮助是很大的(无论是用于分析问题,还是提高生产力).本篇就讲述如何利用Chrome浏览器(这里 ...
- mysql Emoji表情字符集转换
<pre name="code" class="html">Java代码 java.sql.SQLException: Incorrect stri ...
- python核心编程--笔记
python核心编程--笔记 的解释器options: 1.1 –d 提供调试输出 1.2 –O 生成优化的字节码(生成.pyo文件) 1.3 –S 不导入site模块以在启动时查找pyt ...
- MySQL主键添加/删除
2改动数据库和表的字符集alter database maildb default character set utf8;//改动数据库的字符集alter table mailtable defaul ...
- 编译kernel:编译
韦东山Linux视频第1期_裸板_UBoot_文件系统_驱动初步第10课第3节 内核启动流程分析之Makefile.WMV 1. 编译内核分三步: make xxx_defconfig [linux ...
- WCF技术剖析之四:基于IIS的WCF服务寄宿(Hosting)实现揭秘
原文:WCF技术剖析之四:基于IIS的WCF服务寄宿(Hosting)实现揭秘 通过<再谈IIS与ASP.NET管道>的介绍,相信读者已经对IIS和ASP.NET的请求处理管道有了一个大致 ...
- 工作线程AfxBeginThread的使用
工作线程通常用来执行一些后台任务,如:数据计算.后台杀毒等等.因为不需要创建窗口和处理用户消息,编写比较容易,在程序中只要调用AfxBeginThread 函数就可以创建并启动一个工作线程了. Afx ...
- 在JS中,一个自定义函数如何调用另一个自定义函数中的变量
function aa1511() { var chengshi="马鞍山"; var shengfen="安徽省"; return shengfen+&quo ...
- JQuery5.04获取
获取body: $('body'); 或者 $(document.body); 获取元素标签:$('div'); $('a'); 获取ID: $('id'); 获取某个元素的某个属性: $('a ...