由memcpy内存越界引发的问题 && delete 和 delete []的真正区别
今天遇到了一个问题,在程序运行到某处总会报访问到错误的地址的错误,而且每次报错的堆栈还都不一样,排查了一段时间,发现是memcpy这里出了错
char *d = new char[data.size() * ];
memset(d, , data.size() * ); memcpy(d,temp_content.c_str(), temp_content.size());
这里乍一看没什么问题,但是如果这里data字符串为空而temp_content不为空的话,memcpy这样调用就出现了错误。
虽然暂时不会报错,因为这里通过new char[0]申请到了一个内存地址的指针(这里虽然为0但至少应该申请到了1块),这样memset不会报错,即使memset(d, 0, 1000);大概率也不会报错,只要后面的这块连续的内存没被别人占用
所以memcpy(d,temp_content.c_str(), temp_content.size());这种向未申请的内存中写数据也不会报错,但是这样的操作会破坏未申请内存的数据结构,当下一次别的操作申请内存时,申请到被破坏的内存,程序就会报错崩溃了(程序是不会关心你这个指针用的内存属不属于自己,只会关心你有没有用别人的内存!!!)
最好用memcpy_s代替!
delete 和 delete []的真正区别
这个和上面的问题有一点关联度,就是malloc 和 new的时候需要指定申请内存的大小,为什么free和delete时不需要呢?
先解释delete和delete[]的区别,他们同样都会释放指针所指向的内存空间,但如果指针类型不是基本数据结构时,delete只会调用第一个数组内的析构函数,其他的数组成员的析构函数都不会被调用!!!
第二个问题的答案
在学内存分配的问题的时候,malloc和calloc都要指定需要分配内存的大小,但是free的就不需要,我就纳闷free是咋知道从指针地址开始的多少长度是被分配了的?
当时就想,在malloc或者calloc的时候,编译器应该把大小的数值放到哪个地方了,当free的时候就去找那个数值,释放掉数值大小的堆空间。
但是到底放哪呢?
前几天在网上一阵乱逛,说是现代编译器就是把大小的数值放在分配地址开始的之前位置,但是具体在之前多少位置呢?今天在vs的内存监视器里面看到了。
测试代码如下:
[cpp]
#include "stdlib.h"
#include "stdio.h"
#define Num 100
int main(void)
{
int i;
int *p=(int *)malloc(Num);
for (i=0;i<Num;i++)
{
*(p+i)=1; //赋值为1只是为了看起来方便
}
free(p);
return 0;
}
其中p的地址为0x00393220
接着打开vs2008的内存监视器窗口看:
有一个地址为0x00393210的很可疑,因为0x64=100
那么改一下看看:
[cpp]
#define Num 50
再看内存监视器:
看到*(0x00393210)=0x32;即0x32=50
那应该就是把大小放这里了,就是说距离分配地址0x10之前的位置。
从中可以看出为什么分配堆更号内存大小(当然它的主要方面还是“碎片”的产生)的一个小方面~~~
由memcpy内存越界引发的问题 && delete 和 delete []的真正区别的更多相关文章
- C++内存机制中内存溢出、内存泄露、内存越界和栈溢出的区别和联系
当我们在用C++做底层驱动的时候,经常会遇到内存不足的警告,究其原因,往往是因为内存出现溢出,泄露或者越界等原因.那么他们之间有什么联系吗? 内存溢出(out of memory) 是指程序在申请内存 ...
- 使用PageHeap.EXE或GFlags.EXE检查内存越界错误 (转)
2011-05-27 20:19 290人阅读 评论(0) 收藏 举报 microsoftdebuggingstructureoutputimagefile 必先利其器之一:使用PageHeap.EX ...
- 使用PageHeap.EXE或GFlags.EXE检查内存越界错误
必先利其器之一:使用PageHeap.EXE或GFlags.EXE检查内存越界错误 Article last modified on 2002-6-3 ------------------------ ...
- 使用_snscanf_s转换十六进制时引起的内存越界
//将Hex编码转换为指定编码格式的字符串 string Encoding::DecodeHexString(const string &strSrc, UINT code_page ) { ...
- Windows下使用Gflags检查内存越界
环境:windows xp. vs2005 Gflags可用于查找内存越界的问题. 访问一块申请的内存时,当访问的地址超过申请的范围时,就发生了内存越界的问题. 编写测试程序MemoryOverflo ...
- C基础 内存越界和内存监测的简单处理
引言 突然感觉要出去走走了, 醒了后 刷完牙就在联系coding, 不知不觉到了 黄昏. 看看天, 打开灯. 又感觉到了 夜夜夜夜 . 13年到北京务工, 遇到一批批NB的同龄人物. 一块工作, 一块 ...
- C++多线程下出现内存越界问题总结
工作中遇到这样一个问题,某个多级流水多线程的程序,在压力测试下会偶现segmentation fault11错误,错误出现在运行类函数的地方,而后排查后发现是由于多线程争抢导致类被析构后才走入判断,导 ...
- 一次"内存泄漏"引发的血案
本文转载自一次"内存泄漏"引发的血案 导语 2017年末,手Q春节红包项目期间,为保障活动期间服务正常稳定,我对性能不佳的Ark Server进行了改造和重写.重编发布一段时间后, ...
- IOS上解决内存越界访问问题
IOS经常会混合使用C代码,而在C中,对内存的读写是很频繁的操作. 其中,内存越界读写 unsigned char* p =(unsigned char*)malloc(10); unsigned c ...
随机推荐
- python获取命令行参数
python获取命令行参数 主要是通过sys的argv列表来获取命令行内容,命令行的参数以空格分隔放到argv列表中. import sys if __name__ == "__main__ ...
- CentOS7下Django安装
Django安装介绍 安装环境: CentOS7 安装Django比较简单,但需要安装其依赖的东西,还是需要一定时间的.我使用的环境是CentOS Linux release 7.3.1611. 内核 ...
- Signal Handling--ref
http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_21.html A signal is a software interrupt d ...
- Django settings.py添加静态文件夹
我们需要一个静态文件夹来存放文件,例如jQuery的模块 <script src="statics/jquery-3.2.1.js"></script> 引 ...
- AJAX控件——多层弹出Accordion
<asp:Accordion ID="Accordion1" runat="server" ContentCssClass="content&q ...
- MySql 学习(一)
入门使用 show databases; //假设存在seckill 数据库 use seckill; //查看所有表 show tables; //查看某个表的字段,例如存在 student 表 d ...
- Navicat 连接MySQL 8.0.11 出现2059错误
错误 使用Navicat Premium 连接MySQL时出现如下错误: 原因 mysql8 之前的版本中加密规则是mysql_native_password,而在mysql8之后,加密规则是cach ...
- js中的this--执行上下文
条件:函数调用的时候 才有执行上下文 this 不同情况的调用,this也不同 1)当函数直接打点调用,此时的this 是window 2)事件触发函数,此时的this是触发这个事件的对象 3)当对 ...
- jQuery和css3控制箭头丝滑旋转
问题: 我们经常会遇见点击一个小三角使之丝滑的旋转180度上下旋转,怎么实现呢,需要css3搭配jq 来处理 如图:1.点击前 2.点击后(效果丝滑旋转) 1.html ...
- 完美解决Office2003、Office2007、Office2010、Office2013共存方法
原文:http://www.360doc.com/content/14/0903/16/7555793_406799011.shtml 微软Office深受广大用户的青睐,特别是经典的Office 2 ...