概述
某天在工作时,需要在前人的项目代码中的结构体(假定STU)增加数据成员QStringList lst,加好修改后运行时发现程序闪退,debug下调试发现代码崩溃在lst.append()上,于是往前检查代码,发现有memset操作,于是想到了结构体中存在非基本数据类型成员-类对象,如果直接memset会导致破坏类对象的数据结构,必然会导致内存访问异常,而且可能会仅仅释放了类对象的地址,其内部指向的内存空间应该没有释放,应该会导致内存泄漏,为此做了如下测试:
测试代码:
#include <iostream>
using namespace std;
struct STU
{
string str;
};
void Test(string& str)
{
STU stu;
stu.str = str; //! 触发string拷贝构造
cout<<"内存增加"<<endl;
memset(&stu, 0, sizeof(STU));
cout<<"memset"<<endl;
//stu.str.clear();
//cout<<"stu.str.clear()"<<endl;
}
int main(int argc, _TCHAR* argv[])
{
string str = "";
//! 构造1MB内存
for(int i=0;i<=1024*1024;i++)
{
str += "a";
}
Test(str);
cout<<"函数退出,STU析构完毕"<<endl;
return 0;
}
使用memset时:
1、STU构造后,内存占用14.8M
2、触发string拷贝构造后,内存占用15.8M
3、memset后,内存占用15.8M
4、函数返回,STU析构后内存占用15.8M
此时发生了内存泄漏
使用stu.str.clear()时:
1、STU构造后,内存占用13.3M
2、触发string拷贝构造后,内存占用14.3M
3、str.clear()后,内存占用14.3M
4、函数返回,STU析构后内存占用11.5M
结论
当结构体含有非基本类型成员时,应避免使用memset,应在结构体中手动定义清理函数或对成员进行单独清理
struct STU
{
string str;
void clear()
{
str.clear();
}
};
STU stu;
stu.str = "adfa";
stu.clear();
疑惑: 虽然使用memset会破坏结构体中类成员结构,但是当结构体中存在std::string时,使用memset后再对结构体string成员赋值却不会引发程序崩溃,其中的原因是什么?编译器对string的memset有特殊处理?
最后
以上就是丰富小馒头为你收集整理的结构体包含非基本数据类型成员时使用memset会引起内存泄漏结论的全部内容,希望文章能够帮你解决结构体包含非基本数据类型成员时使用memset会引起内存泄漏结论所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复