前段项目中发现一个问题,程序总是在某个dynamic_cast进行动态转换时出异常,查了半天才发现问题原来是出在memset的使用上,虽然问题本身显而易见,但当处于几十万行代码量级中时,就变得不太那么容易定位了。

本文归纳了下使用memset几个需要注意的地方,虽然内容很简单,但也希望对大家有所帮助。
1. memset是以字节为单位,初始化内存块。
当初始化一个字节单位的数组时,可以用memset把每个数组单元初始化成任何你想要的值,比如,
[cpp] view plaincopy print?
  1. char data[10];
  2. memset(data, 1, sizeof(data));    // right
  3. memset(data, 0, sizeof(data));    // right
char data[10];
memset(data, 1, sizeof(data));    // right
memset(data, 0, sizeof(data));    // right
而在初始化其他基础类型时,则需要注意,比如,
[cpp] view plaincopy print?
  1. int data[10];
  2. memset(data, 0, sizeof(data));    // right
  3. memset(data, -1, sizeof(data));    // right
  4. memset(data, 1, sizeof(data));    // wrong, data[x] would be 0x0101 instead of 1
int data[10];
memset(data, 0, sizeof(data));    // right
memset(data, -1, sizeof(data));    // right
memset(data, 1, sizeof(data));    // wrong, data[x] would be 0x0101 instead of 1
2. 当结构体类型中包含指针时,在使用memset初始化时需要小心。
比如如下代码中,
[cpp] view plaincopy print?
  1. struct Parameters {
  2. int x;
  3. int* p_x;
  4. };
  5. Parameters par;
  6. par.p_x = new int[10];
  7. memset(&par, 0, sizeof(par));
struct Parameters {int x;int* p_x;
};
Parameters par;
par.p_x = new int[10];
memset(&par, 0, sizeof(par));
当memset初始化时,并不会初始化p_x指向的int数组单元的值,而会把已经分配过内存的p_x指针本身设置为0,造成内存泄漏。同理,对std::vector等数据类型,显而易见也是不应该使用memset来初始化的。
3. 当结构体或类的本身或其基类中存在虚函数时,也需要谨慎使用memset。
这个问题就是在开头项目中发现的问题,如下代码中,
[cpp] view plaincopy print?
  1. class BaseParameters
  2. {
  3. public:
  4. virtual void reset() {}
  5. };
  6. class MyParameters : public BaseParameters
  7. {
  8. public:
  9. int data[3];
  10. int buf[3];
  11. };
  12. MyParameters my_pars;
  13. memset(&my_pars, 0, sizeof(my_pars));
  14. BaseParameters* pars = &my_pars;
  15. //......
  16. MyParameters* my = dynamic_cast<MyParameters*>(pars);
class BaseParameters
{
public:virtual void reset() {}
};class MyParameters : public BaseParameters
{
public: int data[3];int buf[3];
};MyParameters my_pars;
memset(&my_pars, 0, sizeof(my_pars));
BaseParameters* pars = &my_pars;//......MyParameters* my = dynamic_cast<MyParameters*>(pars);
程序运行到dynamic_cast时发生异常。原因其实也很容易发现,我们的目的是为了初始化数据结构MyParameters里的data和buf,正常来说需要初始化的内存空间是sizeof(int) * 3 * 2 = 24字节,但是使用memset直接初始化MyParameters类型的数据结构时,sizeof(my_pars)却是28字节,因为为了实现多态机制,C++对有虚函数的对象会包含一个指向虚函数表(V-Table)的指针,当使用memset时,会把该虚函数表的指针也初始化为0,而dynamic_cast也使用RTTI技术,运行时会使用到V-Table,可此时由于与V-Table的链接已经被破坏,导致程序发生异常。

老生常谈,正确使用memset相关推荐

  1. 陈词滥调,正确使用memset

    前项目发现一个问题,计划永远是一个dynamic_cast当一个异常动态转换,搜索了半天才发现问题竟然是在memset使用,见.但当处于几十万行代码量级中时,就变得不太那么easy定位了. 本文归纳了 ...

  2. C语言之memset函数的使用

    转自:老生常谈,正确使用memset 本文归纳了下使用memset几个需要注意的地方,虽然内容很简单,但也希望对大家有所帮助. 1. memset是以字节为单位,初始化内存块. 当初始化一个字节单位的 ...

  3. 【C++】memset函数

    memset memset是计算机中C/C++语言初始化函数.作用是将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作. 简单来说,就是将某一块内存的全部内容设置为指定的 ...

  4. memset的用法详解

    文章目录 memset简介 需要说明的几个地方 一.不能任意赋值 二.注意所要赋值的数组的元素类型 关于所要赋值的字符数的写法 具体用法实例 总结 memset简介 memset是一个初始化函数,作用 ...

  5. L1-043 阅览室 (20 分)——memset补充

    L1-043 阅览室 (20 分) 天梯图书阅览室请你编写一个简单的图书借阅统计程序.当读者借书时,管理员输入书号并按下S键,程序开始计时:当读者还书时,管理员输入书号并按下E键,程序结束计时.书号为 ...

  6. 【牛客网】C/C++牛客网专项刷题(02)

    以下为牛客网C/C++专项刷题: 1.虚函数不可以内联,因为虚函数是在运行期的时候确定具体调用的函数,内联是在编译期的时候进行代码展开,两者冲突,所以没有一起使用的做法. 2.C++中构造函数和析构函 ...

  7. wenbao与acm技巧(必备知识)

    推荐博客:http://blog.csdn.net/xueerfei008/article/details/19029797    http://blog.csdn.net/xueerfei008/a ...

  8. 【C/C++17】_ooci.h,_ooci.cpp,_mysql.h,_mysql.cpp,_postgresql.h,_postgresql.cpp

    文章目录 1._ooci.h 2._ooci.cpp 3._mysql.h 4._mysql.cpp 5._postgresql.h 6._postgresql.cpp 1._ooci.h //con ...

  9. Unix编程/应用问答中文版(转)

    Unix编程/应用问答中文版 名称 -- Unix编程/应用问答中文版 版本 -- 0.04 ( 2003-10-09 外发版 ) 维护 -- 小四 <scz@nsfocus.com> 主 ...

最新文章

  1. Nature-2012-拟南芥根系微生物组的结构
  2. Word中的字体大小
  3. 农行笔试,直接寄了,经验总结
  4. 复合索引字段的排序对搜素的影响
  5. golang 筆記:make 與 new 的差別
  6. cocos3 动作回调函数
  7. 安笙机器人_张翰新戏搭档徐璐!包贝尔要和辛芷蕾演奇幻电影?
  8. Linux运维 第三阶段 (一) 网络配置及openssl加密
  9. 银行岗位的“香饽饽”—金融科技岗
  10. 3DMax教程: 3DMax快捷键与界面操作!
  11. Digispark ATtiny85 单片机点灯大师之圣诞节彩灯Merry Christmas
  12. sftp工具都有哪些_自媒体都有哪些做图神器?自媒体人常用的工具
  13. STM32使用FreeRTOS CLI
  14. 【乱七八糟的笔记】——前缀树
  15. python实验过程心得体会_python学习心得
  16. unity 点击UI显示3D爆炸特效
  17. Qt之标签和单行文本编辑框(QLabel、QLineEdit)
  18. 公司里的技术总监CTO,天天都在干些啥?
  19. 我的博客开通啦,以后会记录一位IT女的学习生涯
  20. iOS开发——MRC(手动内存管理)

热门文章

  1. 大学有哪些专业python_python就业方向有哪些?
  2. python绘制指数函数图像及性质_指数函数图像及其性质正式版
  3. linux合并两个文件 去重复,c - 在Linux中使用C,通过系统调用将两个文本文件合并为一个新文件(来回换行) - 堆栈内存溢出...
  4. bilibili有电脑版吗_电脑版和平精英你期待吗?可惜国内并未上线
  5. python居中对齐代码end_Python tkinter.END属性代码示例
  6. BZOJ 1800 [Ahoi2009]fly 飞行棋
  7. MySQL之最基本命令
  8. windows主机网络信息获取程序设计
  9. css 实现页面加载中等待效果
  10. sublimeformaya