- 中国标准城市区域码
- postgresql 截取日期字符串 的函数
- OkHttp 官方中文文档
- 关于java中“使用了未经检查或不安全的操作、有关详细信息,请使用 ——X临潼:unchecked重新编译”
- 什么值得买自动签到自动评论定时任务
- chrome://plugins 无法打开的解决方法,同时解决“该网页已屏蔽插件-adobe flash player”
- 如何在GPT格式下创建EFI和MSR分区(安装WIN10/WIN8.1)
- 联想X270——正版Win10换win7之BIOS配置及系统安装
- 几款开源的堡垒机
- code128条码生成与显示
- Java操作Excel,设置某些单元格不可编辑(HSSFWorkbook ,XSSFWorkbook )
- 第04章-VTK基础(6)
- 通达OA用户操作手册(一)
- postgresql——字符串函数
- (转)C#进行图像处理的几种方法(Bitmap,BitmapData,IntPtr)
- 5.EVE-NG关联SecureCRT,VNC,Wireshark
- Stream 操作 合并两个list
- Unity 利用UGUI打包图集,动态加载sprite资源
- elasticsearch 数据丢失的分析
- win7&win10安装AD管理工具
memset函数导致内存泄露的问题
我们一般常说的内存泄漏是指堆内存的泄漏。程序从堆中分配的内存使用完毕后必须显式释放,否则这块内存就不能被再次使用,即这块内存泄漏了。内存泄漏导致软件在运行过程中占用越来越多的内存,程序的效率会越来越低,从而影响用户的体验,失去市场竞争力。
为了预防内存泄漏我们要求程序使用malloc、new等函数从堆中分配的内存必须在使用完后调用free、delete函数释放该内存。但是如果指向该内存指针的值被修改了,不再指向该内存了,那么即使调用free、delete函数也不会释放该内存,memset函数就会导致这种情况的发生。先来看一下memset函数的声明:
void *memset(void *s, int ch, size_t n); //将s中前n个字节用ch替换并返回s
假如指针s指向的类对象包含指针成员变量,那么在清零的过程中,就会将该指针的值置为0,不再指向原内存空间,原内存空间得不到释放导致内存泄漏。小编在近期的单元测试中就遇到了这个问题。问题发生在使用memset函数对包含string类型的结构体对象进行清零操作。我们先看一下的string类的构造和析构函数的简单实现:
class MString
{
public:
MString(const char *data = NULL);
……….
~MString();
private:
char *str_data;
};
MString::MString(const char *data)
{
try
{str_data = new char[strlen(data) + 1]; }
catch(const bad_alloc &e)
{ cout<<e.what(); abort(); }
strcpy(str_data, data);
}
MString::~MString()
{
delete[] str_data;
}
string类的构造函数在构造string对象时,str_data指针会指向堆中字符串长度加1大小的内存空间,而使用memset函数对string类型对象清零后str_data的值变成了0,指向的原内存空间在析构函数中不会被释放,导致内存泄漏。
因此我们可以得出结论:不要轻易零初始化string、vector等STL标准容器及具有动态内存管理的类。