与内存有关的那些事儿(数组分配空间不够,导致缓冲区溢出,从而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 ...
随机推荐
- BZOJ 1057: [ZJOI2007]棋盘制作( dp + 悬线法 )
对于第一问, 简单的dp. f(i, j)表示以(i, j)为左上角的最大正方形, f(i, j) = min( f(i + 1, j), f(i, j + 1), f(i + 1, j + 1)) ...
- python读取文件内容方法
1) readline 每次读一行,返回序列 2) readlines 一次全部读出,返回序列 3) numpy 的genfromtxt,返回为np的矩阵格式 import numpy as np f ...
- cocos2d-x游戏开发系列教程-中国象棋05-开始游戏
前情回顾 通过CCMainMenu的init函数,已经把所有的按钮,棋子都摆放完毕了,但是这个时候,棋子是不能走动的,只有在开始游戏之后才能移动棋子. 点击
- 全陷阱破解:在Linux环境下的Jenkins中持续集成Androidproject
本方案以 RHEL / Centos 64位Linux操作系统为例,由于这是眼下最常见的server环境. 一.安装Java SDK. 建议,不要使用诸如yum之类的玩意自己主动安装,由于openJD ...
- mysql 初识之日志文件篇
日志文件 1. err日志 error log 记录mysql在运行的过程中所有较为严重的警告和错误信息,以及mysql server每次启动和关闭的详细信息.系统在默认情况下关闭error ...
- redisTemplate 操作
redisDao封装类-其他dao集成他 package com.ffcs.wlan.dao.common; import javax.annotation.Resource; import org. ...
- HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011亚洲北京赛区网络赛)
HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011 亚洲北京赛区网络赛题目) Eliminate Witches! Time Limit: 2000/1000 ...
- EasyUI - DataGrid 组建 - [ 排序功能 ]
效果: 红框的字段看,为设置了,列排序,向后台Post数据sort/order. 原理:向后台POST数据,sort/post数据. html代码: <table id="tab&qu ...
- 拷贝构造函数和const成员函数
实验原因 说明如何使用const描述保护类数据不会意外修改. 编译环境 vc6sp6 + win7x64 工程下载 copyConstruction_constMemberFunction.zip ...
- IOS 应用的架构解析
首先新建一个IOS 的应用工程,主要讲解一下的文件组成: main.m XXXXDelegete.h\.m MainWindow.xib info.plist 文件 IOS 应用程序由UIKit 封装 ...