VC++ 报错:Heap corruption detected
今天在写代码时,发现莫名其妙的错误:
std::string strName = L“testtest”;
char* pOutString = new char(len + 1);
Decrypt((const char*)p, len, pOutString, len + 1);
...
delete pOutString;
pOutString = NULL;
运行到 delete时报错:Heap corruption detected ....
然后我把new 和delete改成数组形式,就一切正常了:
std::string strName = L“testtest”;
int nLen = strName.length();
char* pOutString = new char[len + 1];
Decrypt((const char*)p, len, pOutString, len + 1);
...
delete[] pOutString;
pOutString = NULL;
细想一下,原来是我大意了!!!
(1)
new char[10];分配一块连续的内存,也就是一个数组,里面有10个元素
new char(10);分配一块内存,有一个元素,该元素被初始化为10
char* ch = new char(10) 等效于 :
char* ch = new char;
*ch = 10;
(2)
而产生Heap corruption detected 错误的原因:
当输入超出了预分配的空间大小,就会覆盖该空间之后的一段存储区域,这就叫Heap Corruption。这通常也被用作黑客攻击的一种手段,因为如果在该空间之后的那段存储区域如果是比较重要的数据,就可以利用Heap Corruption来把这些数据修改掉了,后果当然可想而知了。
在VC里面,用release模式编译运行程序的时候,堆分配(Heap allocation)的时候调用的是malloc,如果你要分配10byte的空间,那么就会只分配10byte空间,而用debug模式的时候,堆分配调用的是_malloc_dbg,如果你只要分配10byte的空间,那么它会分配出除了你要的10byte之外,还要多出约36byte空间,用于存储一些薄记信息,debug堆分配出来之后就会按顺序连成一个链。
那么我们再来看看薄记信息中有些什么。还是上面10byte分配空间的例子,那么分配出的10byte空间的前面会有一个32byte的附加信息,存储的是一个_CrtMemBlockHeader结构,可以在DBGINT.H中找到该结构的定义:
typedef struct _CrtMemBlockHeader
{
// Pointer to the block allocated just before this one:
struct _CrtMemBlockHeader *pBlockHeaderNext;
// Pointer to the block allocated just after this one:
struct _CrtMemBlockHeader *pBlockHeaderPrev;
char *szFileName; // File name
int nLine; // Line number
size_t nDataSize; // Size of user block
int nBlockUse; // Type of block
long lRequest; // Allocation number
// Buffer just before (lower than) the user's memory:
unsigned char gap[nNoMansLandSize];
} _CrtMemBlockHeader;
/* In an actual memory block in the debug heap,
* this structure is followed by:
* unsigned char data[nDataSize];
* unsigned char anotherGap[nNoMansLandSize];
*/
结构中的_CrtMemBlockHeader结构两个指针就不用解释是干嘛的了,szFileName是存储的发起分配操作的那行代码所在的文件的路径和名称,而nLine则是行号。nDataSize是请求分配的大小,我们的例子里当然就是10了,nBlockUse是类型,而lRequest是请求号。最后一项gap,又称NoMansLand,是4byte(nNoMansLandSize=4)大小的一段区域,注意看最后几行注释就明白了,在这个结构后面跟的是用户真正需要的10byte数据区域,而其后还跟了一个4byte的Gap,那么也就是说用户申请分配的区域是被一个头结构,和一个4byte的gap包起来的。在释放这10byte空间的时候,会检查这些信息。Gap被分配之后会被以0xFD填充。检查中如果gap中的值变化了,就会以Assert fail的方式报错。不过vc6中提示的比较难懂,DAMAGE :after Normal block(#dd) at 0xhhhhhhhh,而vs2005里面会提示Heap Corruption Detected!而如果你是release版本,那么这个错误就会潜伏直到它的破坏力发生作用。也许其后的区域存储着一个除数,而你的heap corruption把它改写成了0,那么会怎么样呢? :P
至于其他的C/C++编译器中是否会有这样的机制,我就不是很清楚了,或许知道的朋友可以给我做些补充。
下面是我的见解:
我的出错程序:
unsigned int tLength=strlen(inSrcString);
char* tString=new char[tLength]; //注意这里!!!分配的数组大小应为tLength+1,因为最后还有一个'/0'
...
strcpy(tString,inSrcString); //也要小心!如果inSrcString的长度大于tString的长度,会越界,显然Bug!本例先取inSrcString长度
/*附上strcpy大概实现,想然你会明白我的意思。
char* strcpy(char* pDest,const char* pSrc)
{
assert(pDest!=NULL&&pSrc!=NULL);
char* addr=pDest;
while((*pDest++=*pSrc++)!='/0');
retrun addr;
*/
...
delete[] tString; //字符数组,所以用delete[],就是这里报错!!!
我想C++的字符串操作,我是说像我这么原始的,而不是string类,一定要千万小心!!!祝你好运!
VC++ 报错:Heap corruption detected的更多相关文章
- C语言错误: HEAP CORRUPTION DETECTED
程序源代码: //写文件两种方式(文本文件和二进制文件) #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<std ...
- 内存溢出(heap corruption detected:)
今天又遇到了上次出现的bug,然后百度了一下,想起来这是内存溢出的毛病,故记录下来! 出现的问题就是这样: heap corruption detected: after normal block(# ...
- heap corruption detected错误解决方法调试方法以及内存管理相关
1.heap corruption detected http://vopit.blog.51cto.com/2400931/645980 heap corruption detected:aft ...
- HEAP CORRUPTION DETECTED:after Normal block错误方法解决
一:问题描述: 出现的问题如下: 二:问题产生的原因说明 该问题发生于操作堆内存的时候.产生该问题的原因是:你实际使用的内存大小超出了你实际申请的内存大小,在释放内存的时候就会发生该问题. 举个例子: ...
- heap corruption detected VS2015 C语言 报错
申请动态内存时,申请的单元数为n,可用下标为0~n-1 但实际使用时超过了该范围,就会报这个错
- HEAP CORRUPTION DETECTED :after Normal block 错误
http://blog.csdn.net/zhccl/article/details/7889590
- HEAP CORRUPTION DETECTED
发生主要是由于这个问题给写入超出预分配的空间,注意检查越界情况 版权声明:本文博客原创文章,博客,未经同意,不得转载.
- 踩坑之VC报错 error RC2104 : undefined keyword or key name
.RC文件中第541行 MENUITEM "CNDev, ID_CNDEV 少了一个" 正确的应该是MENUITEM " ...
- Vue报错 Duplicate keys detected: '1'. This may cause an update error. vue报错
情况一.错误信息展示为关键字‘keys‘,此时应该检查for循环中的key,循环的key值不为唯一性 (很普通) 情况二.有两个相同的for循环,而这两个for循环的key值是一样的,此时将一个的ke ...
随机推荐
- 使用qmlscene预览qml文件
功能:可以预览qml文件的界面 使用:qmlscene myapp.qml
- Python3基础 str + 字符串变量拼接
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- Django组件(三) Django之中间件
中间件概述 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用不好会影响到性 ...
- luoguP2826 LJJ的数学课
思路 把公式拆开维护两个值,一个a[i]的总和,一个a[i]*i的总和 也可以用树状数组维护,模板题 代码 #include <iostream> #include <vector& ...
- (转)Nuts and Bolts of Applying Deep Learning
Kevin Zakka's Blog About Nuts and Bolts of Applying Deep Learning Sep 26, 2016 This weekend was very ...
- HDU 6103 Kirinriki(尺取法)
http://acm.hdu.edu.cn/showproblem.php?pid=6103 题意: 给出一个字符串,在其中找两串互不重叠的子串,计算它们之间的dis值,要求dis值小于等于m,求能选 ...
- web.xml配置文件详细解读
对于一个J2EE应用的开发者,或者叫java web后台的开发者来说.经常会和web.xml打交道,偶尔用到几个标签不知道啥意思.然后就度娘一下,久而久之虽然大概知道web.xml的基本使用方法,但是 ...
- 【BZOJ】[HNOI2015]菜肴制作
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4010 要是考场上想不出,但是还是有一个分治的做法的嘛 做法就是反向连边,然后再反向输出字典 ...
- Yandex.Algorithm 2011 Round 2 D. Powerful array 莫队
题目链接:点击传送 D. Powerful array time limit per test 5 seconds memory limit per test 256 megabytes input ...
- java编写编译器和解释器
on 2012-07-14 21:24 Bang 阅读(102) 评论(0) 编辑 收藏 续 第二部分 初始后端实现 框架后端支持编译器和解释器.现在框架抽象类Backend有两个极简版实现,一个 ...